@parall/sdk 1.23.0 → 1.25.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/client.d.ts +33 -1
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +106 -6
- package/dist/constants.d.ts +45 -0
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +43 -12
- package/dist/types.d.ts +219 -49
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/client.ts +131 -6
- package/src/constants.ts +47 -12
- package/src/types.ts +272 -49
package/package.json
CHANGED
package/src/client.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { ENDPOINTS } from './constants.js';
|
|
2
2
|
import type {
|
|
3
3
|
AuthTokens,
|
|
4
|
+
AvatarUploadResponse,
|
|
4
5
|
RegisterRequest,
|
|
5
6
|
RegisterResponse,
|
|
6
7
|
LoginRequest,
|
|
@@ -22,6 +23,7 @@ import type {
|
|
|
22
23
|
PatchMessageRequest,
|
|
23
24
|
PaginatedResponse,
|
|
24
25
|
Approval,
|
|
26
|
+
CreateApprovalRequest,
|
|
25
27
|
PresignResponse,
|
|
26
28
|
PresignUploadRequest,
|
|
27
29
|
FileUrlResponse,
|
|
@@ -110,6 +112,15 @@ import type {
|
|
|
110
112
|
UpdateAgentRequest,
|
|
111
113
|
UpdateChatMemberRequest,
|
|
112
114
|
UnreadEntry,
|
|
115
|
+
BillingSummary,
|
|
116
|
+
CreditTransaction,
|
|
117
|
+
CreateCheckoutRequest,
|
|
118
|
+
CreateCheckoutResponse,
|
|
119
|
+
CreateSetupIntentResponse,
|
|
120
|
+
AutoReloadSettings,
|
|
121
|
+
UpdateAutoReloadRequest,
|
|
122
|
+
ComputePricing,
|
|
123
|
+
ComputePricingResponse,
|
|
113
124
|
} from './types.js';
|
|
114
125
|
|
|
115
126
|
export interface ParallClientOptions {
|
|
@@ -287,11 +298,15 @@ export class ParallClient {
|
|
|
287
298
|
}
|
|
288
299
|
|
|
289
300
|
if (!res.ok) {
|
|
290
|
-
const
|
|
301
|
+
const rawErrorBody = await res.json().catch(() => ({}));
|
|
302
|
+
const errorBody = rawErrorBody !== null && typeof rawErrorBody === 'object' ? rawErrorBody as Record<string, unknown> : {};
|
|
291
303
|
const errorObj = errorBody?.error && typeof errorBody.error === 'object' ? errorBody.error as { message?: string; code?: string } : undefined;
|
|
292
304
|
const errMsg = errorObj?.message ?? (typeof errorBody?.error === 'string' ? errorBody.error : undefined);
|
|
293
305
|
const errCode = errorObj?.code ?? (typeof errorBody?.code === 'string' ? errorBody.code : undefined);
|
|
294
|
-
|
|
306
|
+
const apiError = new ApiError(res.status, errMsg ?? res.statusText, errCode);
|
|
307
|
+
const { error: _e, code: _c, message: _m, ...extras } = errorBody;
|
|
308
|
+
if (Object.keys(extras).length > 0) apiError.extras = extras;
|
|
309
|
+
throw apiError;
|
|
295
310
|
}
|
|
296
311
|
|
|
297
312
|
if (res.status === 204) return undefined as T;
|
|
@@ -355,11 +370,15 @@ export class ParallClient {
|
|
|
355
370
|
}
|
|
356
371
|
|
|
357
372
|
if (!res.ok) {
|
|
358
|
-
const
|
|
373
|
+
const rawErrorBody = await res.json().catch(() => ({}));
|
|
374
|
+
const errorBody = rawErrorBody !== null && typeof rawErrorBody === 'object' ? rawErrorBody as Record<string, unknown> : {};
|
|
359
375
|
const errorObj = errorBody?.error && typeof errorBody.error === 'object' ? errorBody.error as { message?: string; code?: string } : undefined;
|
|
360
376
|
const errMsg = errorObj?.message ?? (typeof errorBody?.error === 'string' ? errorBody.error : undefined);
|
|
361
377
|
const errCode = errorObj?.code ?? (typeof errorBody?.code === 'string' ? errorBody.code : undefined);
|
|
362
|
-
|
|
378
|
+
const apiError = new ApiError(res.status, errMsg ?? res.statusText, errCode);
|
|
379
|
+
const { error: _e, code: _c, message: _m, ...extras } = errorBody;
|
|
380
|
+
if (Object.keys(extras).length > 0) apiError.extras = extras;
|
|
381
|
+
throw apiError;
|
|
363
382
|
}
|
|
364
383
|
|
|
365
384
|
if (res.status === 204) return undefined as T;
|
|
@@ -416,6 +435,30 @@ export class ParallClient {
|
|
|
416
435
|
return this.request('PATCH', ENDPOINTS.USERS_ME, data);
|
|
417
436
|
}
|
|
418
437
|
|
|
438
|
+
async deleteAccount(): Promise<void> {
|
|
439
|
+
return this.request('DELETE', ENDPOINTS.USERS_ME);
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
async uploadAvatar(file: File | Blob): Promise<AvatarUploadResponse> {
|
|
443
|
+
const fd = new FormData();
|
|
444
|
+
fd.append('file', file);
|
|
445
|
+
return this.multipartRequest('POST', ENDPOINTS.USER_AVATAR, fd);
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
async deleteAvatar(): Promise<void> {
|
|
449
|
+
return this.request('DELETE', ENDPOINTS.USER_AVATAR);
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
async uploadAgentAvatar(orgId: string, agentId: string, file: File | Blob): Promise<AvatarUploadResponse> {
|
|
453
|
+
const fd = new FormData();
|
|
454
|
+
fd.append('file', file);
|
|
455
|
+
return this.multipartRequest('POST', ENDPOINTS.AGENT_AVATAR(orgId, agentId), fd);
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
async deleteAgentAvatar(orgId: string, agentId: string): Promise<void> {
|
|
459
|
+
return this.request('DELETE', ENDPOINTS.AGENT_AVATAR(orgId, agentId));
|
|
460
|
+
}
|
|
461
|
+
|
|
419
462
|
async getUser(id: string): Promise<User> {
|
|
420
463
|
return this.request('GET', ENDPOINTS.USER(id));
|
|
421
464
|
}
|
|
@@ -680,15 +723,32 @@ export class ParallClient {
|
|
|
680
723
|
|
|
681
724
|
// ---- Approvals ----
|
|
682
725
|
|
|
726
|
+
async getApproval(id: string): Promise<Approval> {
|
|
727
|
+
return this.request('GET', ENDPOINTS.APPROVAL(id));
|
|
728
|
+
}
|
|
729
|
+
|
|
730
|
+
async requestApproval(orgId: string, req: CreateApprovalRequest): Promise<Approval> {
|
|
731
|
+
return this.request('POST', ENDPOINTS.APPROVAL_REQUESTS(orgId), req);
|
|
732
|
+
}
|
|
733
|
+
|
|
683
734
|
async decideApproval(id: string, decision: 'approve' | 'reject'): Promise<Approval> {
|
|
684
735
|
return this.request('POST', ENDPOINTS.APPROVAL_DECIDE(id), { decision });
|
|
685
736
|
}
|
|
686
737
|
|
|
738
|
+
async cancelApproval(id: string): Promise<void> {
|
|
739
|
+
return this.request('POST', ENDPOINTS.APPROVAL_CANCEL(id));
|
|
740
|
+
}
|
|
741
|
+
|
|
687
742
|
async getPendingApprovals(): Promise<Approval[]> {
|
|
688
743
|
const res = await this.request<{ data: Approval[] }>('GET', ENDPOINTS.APPROVALS_PENDING);
|
|
689
744
|
return res.data;
|
|
690
745
|
}
|
|
691
746
|
|
|
747
|
+
async getApprovableActions(): Promise<string[]> {
|
|
748
|
+
const res = await this.request<{ data: string[] }>('GET', ENDPOINTS.APPROVALS_ACTIONS);
|
|
749
|
+
return res.data;
|
|
750
|
+
}
|
|
751
|
+
|
|
692
752
|
// ---- Agents (org-scoped) ----
|
|
693
753
|
|
|
694
754
|
async createAgent(orgId: string, req: CreateAgentRequest): Promise<CreateAgentResponse> {
|
|
@@ -945,6 +1005,10 @@ export class ParallClient {
|
|
|
945
1005
|
return this.request('PATCH', ENDPOINTS.INBOX_ITEM_READ(orgId, id));
|
|
946
1006
|
}
|
|
947
1007
|
|
|
1008
|
+
async markInboxUnread(orgId: string, id: string): Promise<void> {
|
|
1009
|
+
return this.request('PATCH', ENDPOINTS.INBOX_ITEM_UNREAD(orgId, id));
|
|
1010
|
+
}
|
|
1011
|
+
|
|
948
1012
|
async archiveInboxItem(orgId: string, id: string): Promise<void> {
|
|
949
1013
|
return this.request('PATCH', ENDPOINTS.INBOX_ITEM_ARCHIVE(orgId, id));
|
|
950
1014
|
}
|
|
@@ -1012,11 +1076,15 @@ export class ParallClient {
|
|
|
1012
1076
|
if (res.status === 304) return null;
|
|
1013
1077
|
|
|
1014
1078
|
if (!res.ok) {
|
|
1015
|
-
const
|
|
1079
|
+
const rawErrorBody = await res.json().catch(() => ({}));
|
|
1080
|
+
const errorBody = rawErrorBody !== null && typeof rawErrorBody === 'object' ? rawErrorBody as Record<string, unknown> : {};
|
|
1016
1081
|
const errorObj = errorBody?.error && typeof errorBody.error === 'object' ? errorBody.error as { message?: string; code?: string } : undefined;
|
|
1017
1082
|
const errMsg = errorObj?.message ?? (typeof errorBody?.error === 'string' ? errorBody.error : undefined);
|
|
1018
1083
|
const errCode = errorObj?.code ?? (typeof errorBody?.code === 'string' ? errorBody.code : undefined);
|
|
1019
|
-
|
|
1084
|
+
const apiError = new ApiError(res.status, errMsg ?? res.statusText, errCode);
|
|
1085
|
+
const { error: _e, code: _c, message: _m, ...extras } = errorBody;
|
|
1086
|
+
if (Object.keys(extras).length > 0) apiError.extras = extras;
|
|
1087
|
+
throw apiError;
|
|
1020
1088
|
}
|
|
1021
1089
|
|
|
1022
1090
|
return res.json() as Promise<PlatformConfigResponse>;
|
|
@@ -1523,6 +1591,61 @@ export class ParallClient {
|
|
|
1523
1591
|
async getFeatureFlags(orgId: string): Promise<FeatureFlagsResponse> {
|
|
1524
1592
|
return this.request('GET', ENDPOINTS.FEATURE_FLAGS(orgId));
|
|
1525
1593
|
}
|
|
1594
|
+
|
|
1595
|
+
// ---- Billing & Credits (org-scoped) ----
|
|
1596
|
+
|
|
1597
|
+
async getBilling(orgId: string): Promise<BillingSummary> {
|
|
1598
|
+
return this.request('GET', ENDPOINTS.BILLING(orgId));
|
|
1599
|
+
}
|
|
1600
|
+
|
|
1601
|
+
async listBillingTransactions(orgId: string, opts?: { cursor?: string; limit?: number; types?: string[] }): Promise<{ items: CreditTransaction[]; next_cursor: string | null }> {
|
|
1602
|
+
const params = new URLSearchParams();
|
|
1603
|
+
if (opts?.cursor) params.set('cursor', opts.cursor);
|
|
1604
|
+
if (opts?.limit) params.set('limit', String(opts.limit));
|
|
1605
|
+
if (opts?.types?.length) params.set('types', opts.types.join(','));
|
|
1606
|
+
const qs = params.toString();
|
|
1607
|
+
return this.request('GET', `${ENDPOINTS.BILLING_TRANSACTIONS(orgId)}${qs ? `?${qs}` : ''}`);
|
|
1608
|
+
}
|
|
1609
|
+
|
|
1610
|
+
async createCheckout(orgId: string, req: CreateCheckoutRequest): Promise<CreateCheckoutResponse> {
|
|
1611
|
+
return this.request('POST', ENDPOINTS.BILLING_CHECKOUT(orgId), req);
|
|
1612
|
+
}
|
|
1613
|
+
|
|
1614
|
+
/**
|
|
1615
|
+
* Creates a Stripe-hosted card-collection session (Checkout in mode=setup)
|
|
1616
|
+
* and returns the redirect URL. The frontend navigates to `setup_url` and
|
|
1617
|
+
* Stripe handles the card form; the resulting payment_method is recorded
|
|
1618
|
+
* server-side via the `setup_intent.succeeded` webhook. Mirrors
|
|
1619
|
+
* `POST /billing/setup-intent`.
|
|
1620
|
+
*/
|
|
1621
|
+
async createSetupIntent(orgId: string): Promise<CreateSetupIntentResponse> {
|
|
1622
|
+
return this.request('POST', ENDPOINTS.BILLING_SETUP_INTENT(orgId));
|
|
1623
|
+
}
|
|
1624
|
+
|
|
1625
|
+
async getAutoReloadSettings(orgId: string): Promise<AutoReloadSettings> {
|
|
1626
|
+
return this.request('GET', ENDPOINTS.BILLING_AUTO_RELOAD(orgId));
|
|
1627
|
+
}
|
|
1628
|
+
|
|
1629
|
+
async updateAutoReloadSettings(orgId: string, req: UpdateAutoReloadRequest): Promise<AutoReloadSettings> {
|
|
1630
|
+
return this.request('PUT', ENDPOINTS.BILLING_AUTO_RELOAD(orgId), req);
|
|
1631
|
+
}
|
|
1632
|
+
|
|
1633
|
+
// NOTE: `resizeMachine` was intentionally removed before merge — the
|
|
1634
|
+
// matching `PATCH /api/v1/orgs/{orgId}/machines/{machineId}/spec` route
|
|
1635
|
+
// is not yet wired on the server, so exposing the method shipped a
|
|
1636
|
+
// method that always 404'd. Reintroduce together with the server route
|
|
1637
|
+
// when machine in-place resize lands.
|
|
1638
|
+
//
|
|
1639
|
+
// Similarly, the admin grant endpoints (POST/GET /internal/admin/orgs/
|
|
1640
|
+
// {id}/grants) intentionally do NOT live on this public client — they
|
|
1641
|
+
// are mounted on the unauthenticated `/internal/*` surface and reachable
|
|
1642
|
+
// only via internal network paths. The admin dashboard maintains its
|
|
1643
|
+
// own thin client (`ts/admin/lib/api.ts`) that hits these directly.
|
|
1644
|
+
|
|
1645
|
+
async getComputePricing(): Promise<ComputePricingResponse> {
|
|
1646
|
+
const resp = await this.request<{ data: ComputePricingResponse }>('GET', ENDPOINTS.COMPUTE_PRICING());
|
|
1647
|
+
return resp.data;
|
|
1648
|
+
}
|
|
1526
1649
|
}
|
|
1527
1650
|
|
|
1528
1651
|
function normalizeWikiChangeset(changeset: WikiChangeset): WikiChangeset {
|
|
@@ -1534,6 +1657,8 @@ function normalizeWikiChangeset(changeset: WikiChangeset): WikiChangeset {
|
|
|
1534
1657
|
}
|
|
1535
1658
|
|
|
1536
1659
|
export class ApiError extends Error {
|
|
1660
|
+
extras?: Record<string, unknown>;
|
|
1661
|
+
|
|
1537
1662
|
constructor(
|
|
1538
1663
|
public status: number,
|
|
1539
1664
|
message: string,
|
package/src/constants.ts
CHANGED
|
@@ -5,19 +5,24 @@ export const API_BASE = '/api/v1';
|
|
|
5
5
|
export const WIKI_BASE = '/wiki/v1';
|
|
6
6
|
|
|
7
7
|
// LLM model catalog — mirrors server/pkg/llmproxy/models.go DefaultModels.
|
|
8
|
-
// SSOT is the Go side; keep this list in sync when models change.
|
|
8
|
+
// SSOT is the Go side; keep this list in sync when models change. `provider`
|
|
9
|
+
// is used by clients to filter runtime-specific pickers.
|
|
9
10
|
export const PLATFORM_MODELS = [
|
|
10
|
-
{ id: 'anthropic/claude-opus-4.
|
|
11
|
-
{ id: 'anthropic/claude-
|
|
12
|
-
{ id: 'anthropic/claude-sonnet-4.
|
|
13
|
-
{ id: '
|
|
14
|
-
{ id: 'openai/
|
|
15
|
-
{ id: 'openai/gpt-4
|
|
16
|
-
{ id: '
|
|
17
|
-
{ id: '
|
|
18
|
-
{ id: '
|
|
19
|
-
{ id: '
|
|
20
|
-
{ id: '
|
|
11
|
+
{ id: 'anthropic/claude-opus-4.7', name: 'Claude Opus 4.7', provider: 'anthropic' },
|
|
12
|
+
{ id: 'anthropic/claude-opus-4.6', name: 'Claude Opus 4.6', provider: 'anthropic' },
|
|
13
|
+
{ id: 'anthropic/claude-sonnet-4.6', name: 'Claude Sonnet 4.6', provider: 'anthropic' },
|
|
14
|
+
{ id: 'anthropic/claude-sonnet-4.5', name: 'Claude Sonnet 4.5', provider: 'anthropic' },
|
|
15
|
+
{ id: 'openai/gpt-5-codex', name: 'GPT-5 Codex', provider: 'openai' },
|
|
16
|
+
{ id: 'openai/gpt-5.4', name: 'GPT-5.4', provider: 'openai' },
|
|
17
|
+
{ id: 'openai/o4-mini', name: 'o4 Mini', provider: 'openai' },
|
|
18
|
+
{ id: 'openai/gpt-4.1', name: 'GPT-4.1', provider: 'openai' },
|
|
19
|
+
{ id: 'google/gemini-2.5-pro', name: 'Gemini 2.5 Pro', provider: 'google' },
|
|
20
|
+
{ id: 'google/gemini-2.5-flash', name: 'Gemini 2.5 Flash', provider: 'google' },
|
|
21
|
+
{ id: 'moonshotai/kimi-k2.5', name: 'Kimi K2.5', provider: 'moonshotai' },
|
|
22
|
+
{ id: 'z-ai/glm-5', name: 'GLM 5', provider: 'z-ai' },
|
|
23
|
+
{ id: 'deepseek/deepseek-v4-pro', name: 'DeepSeek V4 Pro', provider: 'deepseek' },
|
|
24
|
+
{ id: 'deepseek/deepseek-v4-flash', name: 'DeepSeek V4 Flash', provider: 'deepseek' },
|
|
25
|
+
{ id: 'qwen/qwen3.5-plus-02-15', name: 'Qwen3.5 Plus', provider: 'qwen' },
|
|
21
26
|
] as const;
|
|
22
27
|
|
|
23
28
|
// REST endpoints
|
|
@@ -34,6 +39,7 @@ export const ENDPOINTS = {
|
|
|
34
39
|
|
|
35
40
|
// Users
|
|
36
41
|
USERS_ME: `${API_BASE}/users/me`,
|
|
42
|
+
USER_AVATAR: `${API_BASE}/users/me/avatar`,
|
|
37
43
|
USER: (id: string) => `${API_BASE}/users/${id}`,
|
|
38
44
|
|
|
39
45
|
// WebSocket ticket
|
|
@@ -81,9 +87,15 @@ export const ENDPOINTS = {
|
|
|
81
87
|
UPLOAD_COMPLETE: (orgId: string) => `${API_BASE}/orgs/${orgId}/upload/complete`,
|
|
82
88
|
FILE: (id: string) => `${API_BASE}/files/${id}`,
|
|
83
89
|
|
|
90
|
+
// Approval requests (org-scoped)
|
|
91
|
+
APPROVAL_REQUESTS: (orgId: string) => `${API_BASE}/orgs/${orgId}/approval-requests`,
|
|
92
|
+
|
|
84
93
|
// Approvals (global)
|
|
94
|
+
APPROVAL: (id: string) => `${API_BASE}/approvals/${id}`,
|
|
85
95
|
APPROVAL_DECIDE: (id: string) => `${API_BASE}/approvals/${id}/decide`,
|
|
96
|
+
APPROVAL_CANCEL: (id: string) => `${API_BASE}/approvals/${id}/cancel`,
|
|
86
97
|
APPROVALS_PENDING: `${API_BASE}/approvals/pending`,
|
|
98
|
+
APPROVALS_ACTIONS: `${API_BASE}/approvals/actions`,
|
|
87
99
|
|
|
88
100
|
// Agents (org-scoped)
|
|
89
101
|
AGENTS: (orgId: string) => `${API_BASE}/orgs/${orgId}/agents`,
|
|
@@ -92,6 +104,8 @@ export const ENDPOINTS = {
|
|
|
92
104
|
`${API_BASE}/orgs/${orgId}/agents/${agentId}/api-keys`,
|
|
93
105
|
AGENT_API_KEY: (orgId: string, agentId: string, key: string) =>
|
|
94
106
|
`${API_BASE}/orgs/${orgId}/agents/${agentId}/api-keys/${key}`,
|
|
107
|
+
AGENT_AVATAR: (orgId: string, agentId: string) =>
|
|
108
|
+
`${API_BASE}/orgs/${orgId}/agents/${agentId}/avatar`,
|
|
95
109
|
AGENT_ACTIVITY: (orgId: string, agentId: string) =>
|
|
96
110
|
`${API_BASE}/orgs/${orgId}/agents/${agentId}/activity`,
|
|
97
111
|
AGENT_MONITOR: (orgId: string, agentId: string) =>
|
|
@@ -259,6 +273,7 @@ export const ENDPOINTS = {
|
|
|
259
273
|
INBOX: (orgId: string) => `${API_BASE}/orgs/${orgId}/inbox`,
|
|
260
274
|
INBOX_UNREAD_COUNT: (orgId: string) => `${API_BASE}/orgs/${orgId}/inbox/unread-count`,
|
|
261
275
|
INBOX_ITEM_READ: (orgId: string, id: string) => `${API_BASE}/orgs/${orgId}/inbox/${id}/read`,
|
|
276
|
+
INBOX_ITEM_UNREAD: (orgId: string, id: string) => `${API_BASE}/orgs/${orgId}/inbox/${id}/unread`,
|
|
262
277
|
INBOX_ITEM_ARCHIVE: (orgId: string, id: string) => `${API_BASE}/orgs/${orgId}/inbox/${id}/archive`,
|
|
263
278
|
// Snooze/Unsnooze deferred until un-snooze cron worker is implemented
|
|
264
279
|
INBOX_MARK_ALL_READ: (orgId: string) => `${API_BASE}/orgs/${orgId}/inbox/mark-all-read`,
|
|
@@ -296,6 +311,21 @@ export const ENDPOINTS = {
|
|
|
296
311
|
// Feature flags (org-scoped, server-evaluated)
|
|
297
312
|
FEATURE_FLAGS: (orgId: string) => `${API_BASE}/orgs/${orgId}/feature-flags`,
|
|
298
313
|
|
|
314
|
+
// Billing & Credits (org-scoped)
|
|
315
|
+
BILLING: (orgId: string) => `${API_BASE}/orgs/${orgId}/billing`,
|
|
316
|
+
BILLING_TRANSACTIONS: (orgId: string) => `${API_BASE}/orgs/${orgId}/billing/transactions`,
|
|
317
|
+
BILLING_CHECKOUT: (orgId: string) => `${API_BASE}/orgs/${orgId}/billing/checkout`,
|
|
318
|
+
BILLING_AUTO_RELOAD: (orgId: string) => `${API_BASE}/orgs/${orgId}/billing/auto-reload`,
|
|
319
|
+
BILLING_SETUP_INTENT: (orgId: string) => `${API_BASE}/orgs/${orgId}/billing/setup-intent`,
|
|
320
|
+
// MACHINE_SPEC is intentionally absent until the server registers
|
|
321
|
+
// `PATCH /machines/{machineId}/spec`. Reintroduce with ParallClient.resizeMachine
|
|
322
|
+
// once the in-place resize endpoint lands.
|
|
323
|
+
COMPUTE_PRICING: () => `${API_BASE}/billing/compute-pricing`,
|
|
324
|
+
|
|
325
|
+
// ADMIN_GRANTS intentionally NOT exported here — it sits under the
|
|
326
|
+
// unauthenticated `/internal/admin/*` surface and must not bleed into the
|
|
327
|
+
// public SDK. Admin dashboard hits the URL directly from its own client.
|
|
328
|
+
|
|
299
329
|
} as const;
|
|
300
330
|
|
|
301
331
|
// WebSocket event types
|
|
@@ -354,6 +384,11 @@ export const WS_EVENTS = {
|
|
|
354
384
|
SCHEDULE_UPDATED: 'schedule.updated',
|
|
355
385
|
SCHEDULE_DELETED: 'schedule.deleted',
|
|
356
386
|
SCHEDULE_FIRED: 'schedule.fired',
|
|
387
|
+
BILLING_BALANCE_UPDATED: 'billing.balance_updated',
|
|
388
|
+
BILLING_LOW_BALANCE: 'billing.low_balance',
|
|
389
|
+
BILLING_MACHINE_STOPPED: 'billing.machine_stopped',
|
|
390
|
+
BILLING_INSUFFICIENT: 'billing.insufficient',
|
|
391
|
+
USER_UPDATED: 'user.updated',
|
|
357
392
|
} as const;
|
|
358
393
|
|
|
359
394
|
// Canonical target URI builders for unified comments.
|