@subscribe.dev/client
Version:
JavaScript/TypeScript client for SubscribeDev API - A drop-in for AI generation across 100+ models with built-in billing and rate limiting
495 lines (468 loc) • 15.1 kB
TypeScript
import { default as default_2 } from 'eventemitter3';
/**
* Error thrown when access to a resource is denied
*/
export declare class AccessDeniedError extends SubscribeDevError {
constructor(message: string, requestId?: string);
}
/**
* Error thrown for authentication failures
*/
export declare class AuthenticationError extends SubscribeDevError {
constructor(message: string, requestId?: string);
}
export declare interface BalanceInfo {
allocatedCredits: number;
usedCredits: number;
remainingCredits: number;
}
export declare interface ChatMessage {
role: 'system' | 'user' | 'assistant';
content: string | MultimodalMessageContent[];
}
export declare interface ClientRequest {
model: string;
input: Record<string, unknown>;
response_format?: ResponseFormat;
}
export declare interface ClientResponse {
id: string;
version: string;
urls: {
get: string;
cancel: string;
};
created_at: string;
started_at?: string;
completed_at?: string;
status: 'starting' | 'processing' | 'succeeded' | 'failed' | 'canceled';
input: Record<string, unknown>;
output?: unknown;
error?: string;
logs?: string;
metrics?: {
predict_time?: number;
total_time?: number;
};
}
export declare interface DemoProject {
id: string;
name: string;
description?: string;
ownerId: string;
apiKeyId?: string;
createdAt: string;
updatedAt: string;
apiKey: string;
authCallbackUrl: string | null;
authCallbackEnabled: boolean;
isDemo: boolean;
}
/**
* Error thrown when account has insufficient balance
*/
export declare class InsufficientBalanceError extends SubscribeDevError {
constructor(message: string, remainingCredits?: number, requiredCredits?: number, requestId?: string);
}
export declare interface MultimodalMessageContent {
type: 'text' | 'image_url';
text?: string;
image_url?: {
url: string;
detail?: 'low' | 'high' | 'auto';
};
}
/**
* Error thrown when a resource is not found
*/
export declare class NotFoundError extends SubscribeDevError {
constructor(message: string, requestId?: string);
}
export declare interface PredictionOptions {
}
/**
* Error thrown when rate limit is exceeded
*/
export declare class RateLimitError extends SubscribeDevError {
readonly resetTime?: string;
readonly retryAfter?: number;
constructor(message: string, resetTime?: string, retryAfter?: number, requestId?: string);
}
export declare interface RateLimitInfo {
concurrent: {
allowed: boolean;
currentRequests: number;
maxRequests: number;
reason?: string;
};
minute?: {
allowed: boolean;
currentRequests: number;
maxRequests: number;
resetTime: string;
reason?: string;
};
hour?: {
allowed: boolean;
currentRequests: number;
maxRequests: number;
resetTime: string;
reason?: string;
};
day?: {
allowed: boolean;
currentRequests: number;
maxRequests: number;
resetTime: string;
reason?: string;
};
}
/**
* Response format specification for AI model outputs
*
* @example
* ```typescript
* // JSON object format
* const format1: ResponseFormat = { type: 'json_object' };
*
* // JSON schema format
* const format2: ResponseFormat = {
* type: 'json_schema',
* json_schema: {
* name: 'User',
* schema: { type: 'object', properties: { name: { type: 'string' } } }
* }
* };
*
* // Direct Zod schema (recommended)
* import { z } from 'zod';
* const UserSchema = z.object({ name: z.string() });
* const format3: ResponseFormat = UserSchema;
* ```
*/
export declare type ResponseFormat = {
type: 'json_object';
} | {
type: 'json_schema';
json_schema: {
name: string;
strict?: boolean;
schema: Record<string, unknown>;
};
} | any;
export declare interface StorageOptions {
/** App version for storage isolation (defaults to "default") */
appVersion?: string;
}
/**
* A unified streaming response that supports three different consumption patterns:
* 1. Async iteration: `for await (const chunk of response) { ... }`
* 2. Event-based: `response.on('data', chunk => { ... })`
* 3. Promise-based: `const result = await response` (resolves with final accumulated result)
*/
export declare class StreamableResponse<T = string> extends default_2 implements AsyncIterable<T> {
private readonly sourceIterable;
private _isConsumed;
private _accumulatedResult;
private _promiseResolver;
private _promiseRejecter;
private _consumePromise;
constructor(sourceIterable: AsyncIterable<T>);
/**
* Async iterator implementation - supports `for await...of` loops
*/
[Symbol.asyncIterator](): AsyncIterator<T>;
/**
* Promise implementation - enables `await response` to get final result
*/
then<TResult1 = T, TResult2 = never>(onFulfilled?: ((value: T) => TResult1 | PromiseLike<TResult1>) | null, onRejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | null): Promise<TResult1 | TResult2>;
/**
* Promise catch implementation
*/
catch<TResult = never>(onRejected?: ((reason: any) => TResult | PromiseLike<TResult>) | null): Promise<T | TResult>;
/**
* Promise finally implementation
*/
finally(onFinally?: (() => void) | null): Promise<T>;
/**
* Enhanced event listener with proper typing
*/
on(event: 'data', listener: (chunk: T) => void): this;
on(event: 'end', listener: () => void): this;
on(event: 'error', listener: (error: Error) => void): this;
/**
* Enhanced once listener with proper typing
*/
once(event: 'data', listener: (chunk: T) => void): this;
once(event: 'end', listener: () => void): this;
once(event: 'error', listener: (error: Error) => void): this;
/**
* Start consuming the stream in the background for event listeners and promise resolution
*/
private _consumeInBackground;
/**
* Clone the streamable response to allow multiple consumption patterns
* Note: This requires the underlying source to be re-iterable or cloneable
*/
clone(): StreamableResponse<T>;
/**
* Check if the stream has been consumed
*/
get isConsumed(): boolean;
}
/**
* SubscribeDevClient - Drop-in replacement for Replicate.AI and OpenRouter with end-user-billing and rate limiting
*/
export declare class SubscribeDevClient extends default_2 {
private readonly config;
private readonly queue;
private readonly fetch;
constructor(config: SubscribeDevClientConfig);
get pricingUrl(): string;
get authorizationUrl(): string;
/**
* Run a prediction
* Note: Now returns completed predictions directly - no polling needed
*
* @param model - The model to use for the prediction
* @param options - Configuration options for the prediction
* @param options.input - Input data (can contain prompt OR messages array with multimodal content)
* @param options.response_format - Optional response format specification. Supports:
* - `{ type: 'json_object' }` - Returns a JSON object
* - `{ type: 'json_schema', json_schema: { name: string, schema: object } }` - Returns JSON matching the schema
* - `MyZodSchema` - Pass a Zod schema directly for automatic JSON schema conversion
* @param options.wait - For compatibility - ignored since predictions complete synchronously
* @returns Promise resolving to the prediction result
*
* @example
* ```typescript
* // Basic usage with JSON object response
* const result = await client.run('gpt-4', {
* input: { prompt: 'Hello world' },
* response_format: { type: 'json_object' }
* });
*
* // Using Zod schema directly
* import { z } from 'zod';
* const UserSchema = z.object({
* name: z.string(),
* age: z.number()
* });
*
* const result = await client.run('gpt-4', {
* input: { prompt: 'Generate a user' },
* response_format: UserSchema
* });
* ```
*/
run(model: string, options: {
input: Record<string, any>;
response_format?: ResponseFormat;
wait?: boolean;
stream?: boolean;
}, streamOptions?: {
streamBy?: 'chunk' | 'word' | 'letter';
}): StreamableResponse<string> | Promise<any>;
/**
* Process response format, converting Zod schemas to json_schema format
*/
private processResponseFormat;
/**
* Check if the provided object looks like a Zod schema
*/
private isZodSchema;
/**
* Convert a Zod schema to json_schema format
*/
private convertZodSchema;
/**
* Get account balance information
*/
getBalance(): Promise<BalanceInfo>;
/**
* Get user storage data using auth context
*/
getStorage(options?: StorageOptions): Promise<UserStorage>;
/**
* Update user storage data using auth context
*/
setStorage(sessionData: Record<string, any>, options?: StorageOptions): Promise<UserStorage>;
/**
* Delete user storage data using auth context
*/
deleteStorage(options?: StorageOptions): Promise<void>;
/**
* Get user's subscription status using userKey authentication
* Requires userKey to be provided in client configuration
*/
getSubscriptionStatus(): Promise<SubscriptionStatus>;
/**
* Get comprehensive usage limits and current consumption
* Requires userKey to be provided in client configuration
*/
getUsageLimits(): Promise<UsageLimits>;
/**
* Get comprehensive usage information including credits, rate limits, and consumption
* Alias for getUsageLimits() - Requires userKey to be provided in client configuration
*/
getUsage(): Promise<UsageLimits>;
/**
* Get or create a demo project with a public API key
* Requires userKey (userToken) to be provided in client configuration
* The returned API key is public and safe to share
*/
getDemoProject(): Promise<DemoProject>;
/**
* Make authenticated HTTP request to platform API using userToken as Bearer token
*/
private makePlatformRequest;
/**
* Make authenticated HTTP request to SubscribeDev API
*/
private makeRequest;
/**
* Make authenticated HTTP streaming request to SubscribeDev API
*/
private makeStreamingRequest;
/**
* Create an async iterable from a ReadableStream for streaming responses
*/
private createStreamIterable;
/**
* Handle error responses and throw appropriate error types
*/
private handleErrorResponse;
/**
* Debug logging
*/
private debug;
/**
* Static method to create client (for convenience)
*/
static create(config: SubscribeDevClientConfig): SubscribeDevClient;
}
/**
* Configuration options for the SubscribeDev client
*
* @example
* ```typescript
* const client = new SubscribeDevClient({
* apiKey: 'sk_proj_123...',
* userKey: 'user_456...',
* timeout: 60000,
* debug: true
* });
* ```
*
* @example Basic usage
* ```typescript
* const client = new SubscribeDevClient({
* apiKey: process.env.SUBSCRIBEDEV_API_KEY
* });
* ```
*/
export declare interface SubscribeDevClientConfig {
/** Public API key (project bearer token) */
apiKey?: string;
/** User Bearer token for headless use-cases */
userKey?: string;
/** Access token from auth proxy for x-sub-dev-access-token authentication */
accessToken?: string;
/** API base URL (defaults to production) */
baseUrl?: string;
/** Authorization URL for user sign-in (defaults to auth.subscribe.com) */
authorizationUrl?: string;
/** Request timeout in milliseconds (default: 300000) */
timeout?: number;
/** Maximum retry attempts (default: 3) */
maxRetries?: number;
/** Enable debug logging (default: false) */
debug?: boolean;
}
/**
* Base error class for SubscribeDev client errors
*/
export declare class SubscribeDevError extends Error {
readonly code: string;
readonly statusCode?: number;
readonly details?: Record<string, any>;
readonly requestId?: string;
constructor(message: string, code: string, statusCode?: number, details?: Record<string, any>, requestId?: string);
}
export declare interface SubscriptionStatus {
hasActiveSubscription: boolean;
plan?: {
id: string;
name: string;
price: number;
tokenLimit: number;
subtitle?: string;
description?: string;
features: string[];
};
status: 'active' | 'inactive' | 'cancelled' | 'expired' | 'none';
startedAt?: string;
endsAt?: string;
}
/**
* Error thrown when user is not subscribed (unsubscribed 402 error)
*/
export declare class UnsubscribedError extends SubscribeDevError {
constructor(message: string, requestId?: string);
}
export declare interface UsageLimits {
credits: {
userBalance?: {
allocatedCredits: number;
usedCredits: number;
remainingCredits: number;
lastUpdated: string;
};
limits: {
maxCreditsPerMonth: number;
maxCreditsPerDay: number;
userCreditLimit: number;
};
usage: {
currentMonthUsage: number;
currentDayUsage: number;
};
};
rateLimits: {
concurrent: any;
minute: any;
hour: any;
day: any;
};
modelRestrictions: {
allowedModels: string[];
blockedModels: string[];
};
requestLimits: {
maxConcurrentRequests: number;
currentConcurrentRequests: number;
};
}
export declare interface UserBalance {
projectId: string;
userId: string;
allocatedCredits: number;
usedCredits: number;
remainingCredits: number;
lastUpdated: Date;
}
export declare interface UserStorage {
projectId: string;
userId: string;
appVersion: string;
sessionData: Record<string, any>;
createdAt: string;
updatedAt: string;
}
/**
* Error thrown for request validation failures
*/
export declare class ValidationError extends SubscribeDevError {
constructor(message: string, details?: Record<string, any>, requestId?: string);
}
export { }