runbios-sdk 0.2.1-dev.100

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,230 @@
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 — with reasoning off, no thinking tokens are generated or billed.
66
+ *
67
+ * `'low'` and `'medium'` minimise or skip thinking. `'high'`, `'xhigh'` and
68
+ * `'max'` think, and thinking tokens are billed as output tokens AND count
69
+ * against `max_tokens` — so a small `max_tokens` at those levels can be spent
70
+ * entirely on thinking and return an empty `content` with
71
+ * `finish_reason: "length"`. Budget generously at `'xhigh'`/`'max'`.
72
+ */
73
+ reasoningEffort?: 'none' | 'minimal' | 'low' | 'medium' | 'high' | 'xhigh' | 'max';
74
+ inferenceKey?: string;
75
+ idempotencyKey?: string;
76
+ requestId?: string;
77
+ signal?: AbortSignal;
78
+ }
79
+ export type ChatCompletionResponse = Record<string, unknown>;
80
+ export type ChatCompletionChunk = Record<string, unknown>;
81
+ export declare function validateChatRequest(body: Record<string, unknown>): void;
82
+ export declare function parseSSE(body: ReadableStream<Uint8Array>): AsyncGenerator<string>;
83
+ /**
84
+ * Inference surface. Combines control-plane management of model-serving
85
+ * deployments (`/api/inference*`) with OpenAI-compatible key-scoped inference
86
+ * (`/v1/chat/completions`). Requests are dispatched once; an idempotency header
87
+ * is forwarded but server-side replay is not assumed.
88
+ */
89
+ export declare class Inference {
90
+ private readonly key;
91
+ private readonly baseUrl;
92
+ private readonly timeout;
93
+ private readonly _http;
94
+ constructor(config?: {
95
+ inferenceKey?: string;
96
+ baseUrl?: string;
97
+ timeout?: number;
98
+ }, http?: HttpClient);
99
+ /** @internal Control-plane transport; present when constructed by the SDK client. */
100
+ private get http();
101
+ /** Side-effect-free validation with authoritative stock, prices, alternatives, and hold terms. */
102
+ preflight(params: InferenceCreateParams): Promise<InferencePreflightResponse>;
103
+ /**
104
+ * Create after preflight. Reuse idempotencyKey after a timeout to recover
105
+ * the same deployment and inference key.
106
+ *
107
+ * Pre-submit validation (book-first §2): the chosen gpuType/gpuCount are
108
+ * checked against the server's MODEL-ADDRESSED gpu-options (computed
109
+ * min_gpus/valid_counts) before any POST; a below-minimum or TP-invalid
110
+ * selection throws the typed {@link GpuRejectionError} with the standard
111
+ * body, `permanent: true` and no queue offer. The server stays the
112
+ * enforcement floor; an unreadable sizing endpoint never blocks the create.
113
+ *
114
+ * That advisory check is SKIPPED whenever its sizing basis cannot be
115
+ * trusted -- when an explicit `contextLength` cannot be proven to fit the
116
+ * model's native window, and equally when the value is not one this client
117
+ * can read as a window at all (a string from a JSON config, a fraction, a
118
+ * boolean). `contextLength` feeds KV sizing, so an over-native value inflates
119
+ * `min_gpus` and would make this client synthesize a "buy more GPUs" 409 for
120
+ * what is really one bad parameter. The server answers that case correctly
121
+ * (400 `context_length N exceeds the model's maximum of M`), so it is left to
122
+ * answer it.
123
+ *
124
+ * Book-before-reveal (book-first §1): a non-queued create answers 202 with
125
+ * a booking handle while a real GPU is secured (30-40s typical).
126
+ * By default this method POLLS the booking to its terminal outcome and
127
+ * returns the full create payload (the one-time inference_key exactly
128
+ * once); a definitive miss throws {@link GpuRejectionError} with
129
+ * FRESH alternatives + the minimum block, and NO deployment exists. Pass
130
+ * `{ waitForBooking: false }` to receive the raw 202 body and poll
131
+ * {@link getBooking} yourself. Transient 503s during the poll are retried —
132
+ * a market outage is never a capacity verdict.
133
+ */
134
+ create(params: InferenceCreateParams, idempotencyKey: string): Promise<InferenceCreateResponse>;
135
+ create(params: InferenceCreateParams, idempotencyKey: string, options: {
136
+ waitForBooking?: boolean;
137
+ bookingTimeoutMs?: number;
138
+ }): Promise<InferenceCreateResponse | InferenceBookingAccepted>;
139
+ /**
140
+ * Poll a pre-reveal booking handle once: `{ booking: {...} }` while pending,
141
+ * or the full create payload once the GPU is secured (the one-time
142
+ * inference_key is present exactly once). Throws
143
+ * {@link GpuRejectionError} on the definitive 409 stock miss and ApiError
144
+ * 503 on a transient market outage (retry — never a capacity verdict).
145
+ */
146
+ getBooking(handle: string): Promise<InferenceCreateResponse | InferenceBookingAccepted>;
147
+ /** Poll a booking handle to its terminal outcome (see {@link create}). */
148
+ waitForBooking(handle: string, timeoutMs?: number, pollIntervalMs?: number): Promise<InferenceCreateResponse>;
149
+ /**
150
+ * Whether the advisory capacity check may run on this context length.
151
+ *
152
+ * `contextLength` is an INPUT to KV-cache sizing. An over-native value
153
+ * inflates the KV estimate, raises the computed `min_gpus`, and would make
154
+ * {@link validateGpuSelectionBeforeSubmit} synthesize a 409 telling the
155
+ * caller to buy more GPUs — when the real problem is one parameter and the
156
+ * server's own verdict is a 400 (`context_length N exceeds the model's
157
+ * maximum of M`). A client must never fabricate a capacity verdict the server
158
+ * would not give.
159
+ *
160
+ * True only when the sizing basis is sound: no explicit `contextLength` (the
161
+ * server sizes from `min(nativeMax, 262144)`, which can never exceed native),
162
+ * or a window PROVEN to fit the registry's recorded native max. False when
163
+ * the registry says the context is over native, when the native max cannot be
164
+ * read at all, or when the value is not one this client can read as a window
165
+ * (see {@link contextSizingBasis}) — all of them hand the question to the
166
+ * server, which answers authoritatively before any wallet hold or GPU
167
+ * booking. The decision never depends on the runtime type the caller passed:
168
+ * `'999999'` from a JSON config skips the check exactly like `999999` does.
169
+ * @internal
170
+ */
171
+ private contextSizingIsTrustworthy;
172
+ /**
173
+ * Advisory model-addressed min/valid-count check before any POST. Throws the
174
+ * typed GpuRejectionError only when the selection can NEVER be booked for
175
+ * this model, so it always carries a permanent code and no queue offer; every
176
+ * failure to ANSWER (endpoint unreachable, unknown shape, an untrustworthy
177
+ * context length) is silent — the create gate re-validates authoritatively
178
+ * and unknown never fails closed. @internal
179
+ */
180
+ private validateGpuSelectionBeforeSubmit;
181
+ /** Fetch one bounded newest-first page. Reuse next_cursor with unchanged filters. */
182
+ listPage(params?: InferenceListParams): Promise<InferenceListResponse>;
183
+ /**
184
+ * Compatibility helper returning only one bounded page. Prefer listPage for
185
+ * pagination.
186
+ *
187
+ * These are LIST rows, not details: the model handle is `model_ref` (there is
188
+ * no `model` key) and the per-row serving settings are absent. Call
189
+ * {@link get} for the full deployment.
190
+ */
191
+ list(params?: InferenceListParams): Promise<InferenceDeploymentSummary[]>;
192
+ /**
193
+ * Lazily traverse pages without materializing an unbounded tenant list.
194
+ * Yields LIST rows (see {@link list}), not details.
195
+ */
196
+ iterate(params?: Omit<InferenceListParams, 'cursor'>): AsyncGenerator<InferenceDeploymentSummary, void, void>;
197
+ /**
198
+ * Current durable lifecycle, queue, price-cap, and wallet-authorization state.
199
+ *
200
+ * Unlike a {@link list} row this resolves the per-deployment serving settings
201
+ * — `context_length` and its `native_max_context` ceiling, `quantization`,
202
+ * `serving_config`, the applied-vs-requested snapshot, tool/reasoning
203
+ * capability, and `available_actions` — and it exposes the model handle as
204
+ * `hf_model_id` / `base_model_id` while `model` aliases the deployment name.
205
+ */
206
+ get(id: string): Promise<InferenceDeployment>;
207
+ /** Alias for get(), useful in polling automations. */
208
+ status(id: string): Promise<InferenceDeployment>;
209
+ /** Durable email delivery history, including bounded retries and dead letters. */
210
+ notifications(id: string, limit?: number): Promise<InferenceNotificationListResponse['notifications']>;
211
+ stop(id: string): Promise<InferenceLifecycleResponse>;
212
+ resume(id: string): Promise<InferenceLifecycleResponse>;
213
+ restart(id: string): Promise<InferenceLifecycleResponse>;
214
+ update(id: string, params: InferenceUpdateParams): Promise<InferenceUpdateResponse>;
215
+ delete(id: string): Promise<InferenceDeleteResponse>;
216
+ /**
217
+ * Model-fit GPU choices joined to the authoritative deployment market
218
+ * snapshot. MODEL-ADDRESSED (recommended, book-first §2): pass `model` (or
219
+ * `inferenceId`) and the SERVER resolves the facts and computes
220
+ * min_gpus/valid_counts/bookable_counts — the same single implementation the
221
+ * create gate enforces, so client facts can never understate a minimum. The
222
+ * client-fact params (`paramsB` & friends) are DEPRECATED, kept one release.
223
+ */
224
+ getGPUOptions(params: InferenceGPUOptionsParams): Promise<InferenceGPUOptionsResponse>;
225
+ private prepare;
226
+ private abortContext;
227
+ chatCompletions(params: ChatCompletionParams): Promise<ChatCompletionResponse>;
228
+ streamChatCompletions(params: ChatCompletionParams): AsyncGenerator<ChatCompletionChunk>;
229
+ }
230
+ export { buildInferenceRequest };