runbios-sdk 0.2.1-dev.62

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.
@@ -0,0 +1,101 @@
1
+ /**
2
+ * View GPU pricing, availability, and get recommendations for your model.
3
+ */
4
+ export class GPU {
5
+ _http;
6
+ /** @internal */
7
+ constructor(_http) {
8
+ this._http = _http;
9
+ }
10
+ /**
11
+ * Get pricing and availability for all GPU types.
12
+ *
13
+ * Returns the full catalog of GPUs with per-hour pricing, VRAM,
14
+ * and which training methods each supports.
15
+ *
16
+ * @example
17
+ * ```ts
18
+ * const pricing = await client.gpu.getPricing();
19
+ * for (const gpu of pricing.gpus) {
20
+ * console.log(`${gpu.display_name}: ${gpu.price_display} -- ${gpu.vram_gb}GB VRAM`);
21
+ * }
22
+ * ```
23
+ */
24
+ async getPricing() {
25
+ return this._http.fetchGet('/api/public/gpu-pricing');
26
+ }
27
+ /**
28
+ * Get authoritative, model-aware training GPU options with live stock,
29
+ * required counts, total prices, and alternatives when nothing is bookable.
30
+ */
31
+ async getOptions(params) {
32
+ const q = new URLSearchParams({
33
+ model_id: params.modelId,
34
+ train_type: String(params.trainType || params.adapter || 'lora'),
35
+ });
36
+ if (params.modelRevision)
37
+ q.set('model_revision', params.modelRevision);
38
+ if (params.integrationId)
39
+ q.set('integration_id', params.integrationId);
40
+ if (params.method)
41
+ q.set('method', params.method);
42
+ if (params.rlhfType)
43
+ q.set('rlhf_type', params.rlhfType);
44
+ if (params.modelParamsB !== undefined)
45
+ q.set('model_params_b', String(params.modelParamsB));
46
+ if (params.modelActiveParamsB !== undefined) {
47
+ q.set('model_active_params_b', String(params.modelActiveParamsB));
48
+ }
49
+ return this._http.fetchGet(`/api/training/gpu-options?${q}`);
50
+ }
51
+ /**
52
+ * Get the recommended GPU configuration for a specific model.
53
+ *
54
+ * Uses the model's parameter count and architecture to suggest
55
+ * the best GPU type and count for training.
56
+ *
57
+ * @param modelId - Full model id (e.g. "meta-llama/Llama-3.1-8B-Instruct").
58
+ *
59
+ * @example
60
+ * ```ts
61
+ * const rec = await client.gpu.getRecommended('meta-llama/Llama-3.1-8B-Instruct');
62
+ * if (rec) {
63
+ * console.log(`Recommended: ${rec.display_name} x${rec.recommended_count}`);
64
+ * }
65
+ * ```
66
+ */
67
+ async getRecommended(modelId) {
68
+ const options = await this.getOptions({ modelId, trainType: 'lora', method: 'sft' });
69
+ const recommended = options.recommended;
70
+ if (!recommended)
71
+ return null;
72
+ const option = options.options.find((item) => item.gpu_type === recommended.gpu_type);
73
+ if (!option?.bookable)
74
+ return null;
75
+ // Preserve the legacy recommendation shape while deriving sizing, stock,
76
+ // and total cost from the same authoritative endpoint as job creation.
77
+ const pricing = await this.getPricing();
78
+ const catalog = pricing.gpus.find((item) => item.gpu_type === recommended.gpu_type);
79
+ const pricePerGPU = recommended.price_per_hour_cents || option.price_per_hour_cents;
80
+ return {
81
+ gpu_type: recommended.gpu_type,
82
+ display_name: catalog?.display_name || option.display_name,
83
+ vram_gb: catalog?.vram_gb || option.vram_gb,
84
+ tier: catalog?.tier || '',
85
+ best_for: catalog?.best_for || '',
86
+ max_gpu_count: catalog?.max_gpu_count || option.max_gpu_count,
87
+ default_storage_gb: recommended.storage_gb,
88
+ param_range: catalog?.param_range || '',
89
+ methods: catalog?.methods || '',
90
+ available: option.available,
91
+ available_count: option.available_count,
92
+ price_per_hour_cents: pricePerGPU,
93
+ price_display: catalog?.price_display || `$${(pricePerGPU / 100).toFixed(2)}/hr`,
94
+ recommended_count: recommended.gpu_count,
95
+ total_vram_gb: option.vram_gb * recommended.gpu_count,
96
+ estimated_cost_per_hour_cents: recommended.total_price_per_hour_cents,
97
+ model_params_b: options.model_params_b,
98
+ reason: 'Cheapest currently bookable configuration that meets the model and adapter requirements',
99
+ };
100
+ }
101
+ }
@@ -0,0 +1,224 @@
1
+ import type { HttpClient } from '../client.js';
2
+ import type { InferenceDeployment, InferenceDeploymentSummary, InferenceBookingAccepted, InferenceCreateParams, InferenceCreateResponse, InferenceDeleteResponse, InferenceGPUOptionsParams, InferenceGPUOptionsResponse, InferenceLifecycleResponse, InferenceListParams, InferenceListResponse, InferenceNotificationListResponse, InferencePreflightResponse, InferenceUpdateResponse, InferenceUpdateParams } from '../types.js';
3
+ /**
4
+ * Serving context-length policy, owned and enforced by the server. Mirrored
5
+ * here for documentation only -- never to pre-empt a server verdict.
6
+ *
7
+ * default = min(nativeMax, CONTEXT_DEFAULT_CEILING)
8
+ * the window is editable only when nativeMax exceeds CONTEXT_EDITABLE_FLOOR,
9
+ * and a request can NEVER exceed the model's own nativeMax (that is a 400).
10
+ *
11
+ * CONTEXT_EDITABLE_FLOOR doubles as the default when the native window is
12
+ * unknown; a genuinely small-context model keeps its own native window rather
13
+ * than being raised to the floor.
14
+ */
15
+ export declare const CONTEXT_DEFAULT_CEILING = 262144;
16
+ export declare const CONTEXT_EDITABLE_FLOOR = 32768;
17
+ /**
18
+ * The sizing BASIS the advisory capacity check is allowed to reason from —
19
+ * what window the SERVER will size the request at, as far as this client can
20
+ * prove it. Deliberately not "what type did the caller pass": the trust
21
+ * decision must be identical for the same over-native window whether it
22
+ * arrives as `999999` or `'999999'` (TypeScript types are erased, and a JSON
23
+ * config, a form field or a plain-JS caller all hand over strings).
24
+ *
25
+ * - `server_default` — no window asked for. The server sizes
26
+ * `min(nativeMax, CONTEXT_DEFAULT_CEILING)`, which can never exceed native,
27
+ * and treats `null` and any non-positive value the same way. Sound with no
28
+ * extra request.
29
+ * - `explicit` — an integral window this client can compare against the
30
+ * registry's native max.
31
+ * - `unprovable` — anything else. Coercing it and then trusting the result
32
+ * would put the fabricated verdict straight back: a numeric string reaches
33
+ * the sizing endpoint verbatim as a query param and inflates `min_gpus`
34
+ * exactly like the number. @internal
35
+ */
36
+ export type ContextSizingBasis = 'server_default' | 'explicit' | 'unprovable';
37
+ export declare function contextSizingBasis(requested: unknown): [ContextSizingBasis, number];
38
+ declare function buildInferenceRequest(params: InferenceCreateParams): Record<string, unknown>;
39
+ export interface ChatMessage extends Record<string, unknown> {
40
+ role: 'system' | 'developer' | 'user' | 'assistant' | 'tool' | 'function';
41
+ content?: unknown;
42
+ }
43
+ export interface FunctionTool extends Record<string, unknown> {
44
+ type: 'function';
45
+ function: {
46
+ name: string;
47
+ description?: string;
48
+ parameters?: Record<string, unknown>;
49
+ strict?: boolean;
50
+ };
51
+ }
52
+ export interface ChatCompletionParams extends Record<string, unknown> {
53
+ messages: ChatMessage[];
54
+ model?: string;
55
+ tools?: FunctionTool[];
56
+ toolChoice?: 'none' | 'auto' | 'required' | {
57
+ type: 'function';
58
+ function: {
59
+ name: string;
60
+ };
61
+ };
62
+ /**
63
+ * Standardized reasoning effort. Forwarded to `/v1/chat/completions` as
64
+ * `reasoning_effort`. Use `'none'` to disable reasoning where the model
65
+ * allows it.
66
+ */
67
+ reasoningEffort?: 'none' | 'minimal' | 'low' | 'medium' | 'high' | 'max';
68
+ inferenceKey?: string;
69
+ idempotencyKey?: string;
70
+ requestId?: string;
71
+ signal?: AbortSignal;
72
+ }
73
+ export type ChatCompletionResponse = Record<string, unknown>;
74
+ export type ChatCompletionChunk = Record<string, unknown>;
75
+ export declare function validateChatRequest(body: Record<string, unknown>): void;
76
+ export declare function parseSSE(body: ReadableStream<Uint8Array>): AsyncGenerator<string>;
77
+ /**
78
+ * Inference surface. Combines control-plane management of model-serving
79
+ * deployments (`/api/inference*`) with OpenAI-compatible key-scoped inference
80
+ * (`/v1/chat/completions`). Requests are dispatched once; an idempotency header
81
+ * is forwarded but server-side replay is not assumed.
82
+ */
83
+ export declare class Inference {
84
+ private readonly key;
85
+ private readonly baseUrl;
86
+ private readonly timeout;
87
+ private readonly _http;
88
+ constructor(config?: {
89
+ inferenceKey?: string;
90
+ baseUrl?: string;
91
+ timeout?: number;
92
+ }, http?: HttpClient);
93
+ /** @internal Control-plane transport; present when constructed by the SDK client. */
94
+ private get http();
95
+ /** Side-effect-free validation with authoritative stock, prices, alternatives, and hold terms. */
96
+ preflight(params: InferenceCreateParams): Promise<InferencePreflightResponse>;
97
+ /**
98
+ * Create after preflight. Reuse idempotencyKey after a timeout to recover
99
+ * the same deployment and inference key.
100
+ *
101
+ * Pre-submit validation (book-first §2): the chosen gpuType/gpuCount are
102
+ * checked against the server's MODEL-ADDRESSED gpu-options (computed
103
+ * min_gpus/valid_counts) before any POST; a below-minimum or TP-invalid
104
+ * selection throws the typed {@link GpuRejectionError} with the standard
105
+ * body, `permanent: true` and no queue offer. The server stays the
106
+ * enforcement floor; an unreadable sizing endpoint never blocks the create.
107
+ *
108
+ * That advisory check is SKIPPED whenever its sizing basis cannot be
109
+ * trusted -- when an explicit `contextLength` cannot be proven to fit the
110
+ * model's native window, and equally when the value is not one this client
111
+ * can read as a window at all (a string from a JSON config, a fraction, a
112
+ * boolean). `contextLength` feeds KV sizing, so an over-native value inflates
113
+ * `min_gpus` and would make this client synthesize a "buy more GPUs" 409 for
114
+ * what is really one bad parameter. The server answers that case correctly
115
+ * (400 `context_length N exceeds the model's maximum of M`), so it is left to
116
+ * answer it.
117
+ *
118
+ * Book-before-reveal (book-first §1): a non-queued create answers 202 with
119
+ * a booking handle while a real GPU is secured (30-40s typical).
120
+ * By default this method POLLS the booking to its terminal outcome and
121
+ * returns the full create payload (the one-time inference_key exactly
122
+ * once); a definitive miss throws {@link GpuRejectionError} with
123
+ * FRESH alternatives + the minimum block, and NO deployment exists. Pass
124
+ * `{ waitForBooking: false }` to receive the raw 202 body and poll
125
+ * {@link getBooking} yourself. Transient 503s during the poll are retried —
126
+ * a market outage is never a capacity verdict.
127
+ */
128
+ create(params: InferenceCreateParams, idempotencyKey: string): Promise<InferenceCreateResponse>;
129
+ create(params: InferenceCreateParams, idempotencyKey: string, options: {
130
+ waitForBooking?: boolean;
131
+ bookingTimeoutMs?: number;
132
+ }): Promise<InferenceCreateResponse | InferenceBookingAccepted>;
133
+ /**
134
+ * Poll a pre-reveal booking handle once: `{ booking: {...} }` while pending,
135
+ * or the full create payload once the GPU is secured (the one-time
136
+ * inference_key is present exactly once). Throws
137
+ * {@link GpuRejectionError} on the definitive 409 stock miss and ApiError
138
+ * 503 on a transient market outage (retry — never a capacity verdict).
139
+ */
140
+ getBooking(handle: string): Promise<InferenceCreateResponse | InferenceBookingAccepted>;
141
+ /** Poll a booking handle to its terminal outcome (see {@link create}). */
142
+ waitForBooking(handle: string, timeoutMs?: number, pollIntervalMs?: number): Promise<InferenceCreateResponse>;
143
+ /**
144
+ * Whether the advisory capacity check may run on this context length.
145
+ *
146
+ * `contextLength` is an INPUT to KV-cache sizing. An over-native value
147
+ * inflates the KV estimate, raises the computed `min_gpus`, and would make
148
+ * {@link validateGpuSelectionBeforeSubmit} synthesize a 409 telling the
149
+ * caller to buy more GPUs — when the real problem is one parameter and the
150
+ * server's own verdict is a 400 (`context_length N exceeds the model's
151
+ * maximum of M`). A client must never fabricate a capacity verdict the server
152
+ * would not give.
153
+ *
154
+ * True only when the sizing basis is sound: no explicit `contextLength` (the
155
+ * server sizes from `min(nativeMax, 262144)`, which can never exceed native),
156
+ * or a window PROVEN to fit the registry's recorded native max. False when
157
+ * the registry says the context is over native, when the native max cannot be
158
+ * read at all, or when the value is not one this client can read as a window
159
+ * (see {@link contextSizingBasis}) — all of them hand the question to the
160
+ * server, which answers authoritatively before any wallet hold or GPU
161
+ * booking. The decision never depends on the runtime type the caller passed:
162
+ * `'999999'` from a JSON config skips the check exactly like `999999` does.
163
+ * @internal
164
+ */
165
+ private contextSizingIsTrustworthy;
166
+ /**
167
+ * Advisory model-addressed min/valid-count check before any POST. Throws the
168
+ * typed GpuRejectionError only when the selection can NEVER be booked for
169
+ * this model, so it always carries a permanent code and no queue offer; every
170
+ * failure to ANSWER (endpoint unreachable, unknown shape, an untrustworthy
171
+ * context length) is silent — the create gate re-validates authoritatively
172
+ * and unknown never fails closed. @internal
173
+ */
174
+ private validateGpuSelectionBeforeSubmit;
175
+ /** Fetch one bounded newest-first page. Reuse next_cursor with unchanged filters. */
176
+ listPage(params?: InferenceListParams): Promise<InferenceListResponse>;
177
+ /**
178
+ * Compatibility helper returning only one bounded page. Prefer listPage for
179
+ * pagination.
180
+ *
181
+ * These are LIST rows, not details: the model handle is `model_ref` (there is
182
+ * no `model` key) and the per-row serving settings are absent. Call
183
+ * {@link get} for the full deployment.
184
+ */
185
+ list(params?: InferenceListParams): Promise<InferenceDeploymentSummary[]>;
186
+ /**
187
+ * Lazily traverse pages without materializing an unbounded tenant list.
188
+ * Yields LIST rows (see {@link list}), not details.
189
+ */
190
+ iterate(params?: Omit<InferenceListParams, 'cursor'>): AsyncGenerator<InferenceDeploymentSummary, void, void>;
191
+ /**
192
+ * Current durable lifecycle, queue, price-cap, and wallet-authorization state.
193
+ *
194
+ * Unlike a {@link list} row this resolves the per-deployment serving settings
195
+ * — `context_length` and its `native_max_context` ceiling, `quantization`,
196
+ * `serving_config`, the applied-vs-requested snapshot, tool/reasoning
197
+ * capability, and `available_actions` — and it exposes the model handle as
198
+ * `hf_model_id` / `base_model_id` while `model` aliases the deployment name.
199
+ */
200
+ get(id: string): Promise<InferenceDeployment>;
201
+ /** Alias for get(), useful in polling automations. */
202
+ status(id: string): Promise<InferenceDeployment>;
203
+ /** Durable email delivery history, including bounded retries and dead letters. */
204
+ notifications(id: string, limit?: number): Promise<InferenceNotificationListResponse['notifications']>;
205
+ stop(id: string): Promise<InferenceLifecycleResponse>;
206
+ resume(id: string): Promise<InferenceLifecycleResponse>;
207
+ restart(id: string): Promise<InferenceLifecycleResponse>;
208
+ update(id: string, params: InferenceUpdateParams): Promise<InferenceUpdateResponse>;
209
+ delete(id: string): Promise<InferenceDeleteResponse>;
210
+ /**
211
+ * Model-fit GPU choices joined to the authoritative deployment market
212
+ * snapshot. MODEL-ADDRESSED (recommended, book-first §2): pass `model` (or
213
+ * `inferenceId`) and the SERVER resolves the facts and computes
214
+ * min_gpus/valid_counts/bookable_counts — the same single implementation the
215
+ * create gate enforces, so client facts can never understate a minimum. The
216
+ * client-fact params (`paramsB` & friends) are DEPRECATED, kept one release.
217
+ */
218
+ getGPUOptions(params: InferenceGPUOptionsParams): Promise<InferenceGPUOptionsResponse>;
219
+ private prepare;
220
+ private abortContext;
221
+ chatCompletions(params: ChatCompletionParams): Promise<ChatCompletionResponse>;
222
+ streamChatCompletions(params: ChatCompletionParams): AsyncGenerator<ChatCompletionChunk>;
223
+ }
224
+ export { buildInferenceRequest };