langtrain 0.2.6 → 0.2.9

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/index.js CHANGED
@@ -1,2 +1,2 @@
1
- 'use strict';var chunkN6MFB652_js=require('./chunk-N6MFB652.js');Object.defineProperty(exports,"AgentClient",{enumerable:true,get:function(){return chunkN6MFB652_js.d}});Object.defineProperty(exports,"AgentTypes",{enumerable:true,get:function(){return chunkN6MFB652_js.e}});Object.defineProperty(exports,"BaseClient",{enumerable:true,get:function(){return chunkN6MFB652_js.c}});Object.defineProperty(exports,"FileClient",{enumerable:true,get:function(){return chunkN6MFB652_js.f}});Object.defineProperty(exports,"GuardrailClient",{enumerable:true,get:function(){return chunkN6MFB652_js.m}});Object.defineProperty(exports,"LangtrainError",{enumerable:true,get:function(){return chunkN6MFB652_js.b}});Object.defineProperty(exports,"Langtune",{enumerable:true,get:function(){return chunkN6MFB652_js.r}});Object.defineProperty(exports,"Langvision",{enumerable:true,get:function(){return chunkN6MFB652_js.q}});Object.defineProperty(exports,"ModelClient",{enumerable:true,get:function(){return chunkN6MFB652_js.i}});Object.defineProperty(exports,"ModelTypes",{enumerable:true,get:function(){return chunkN6MFB652_js.j}});Object.defineProperty(exports,"SecretClient",{enumerable:true,get:function(){return chunkN6MFB652_js.k}});Object.defineProperty(exports,"SecretTypes",{enumerable:true,get:function(){return chunkN6MFB652_js.l}});Object.defineProperty(exports,"SubscriptionClient",{enumerable:true,get:function(){return chunkN6MFB652_js.h}});Object.defineProperty(exports,"Text",{enumerable:true,get:function(){return chunkN6MFB652_js.p}});Object.defineProperty(exports,"TrainingClient",{enumerable:true,get:function(){return chunkN6MFB652_js.g}});Object.defineProperty(exports,"UsageClient",{enumerable:true,get:function(){return chunkN6MFB652_js.n}});Object.defineProperty(exports,"Vision",{enumerable:true,get:function(){return chunkN6MFB652_js.o}});//# sourceMappingURL=index.js.map
1
+ 'use strict';var chunkJVHUW2HM_js=require('./chunk-JVHUW2HM.js');Object.defineProperty(exports,"AgentClient",{enumerable:true,get:function(){return chunkJVHUW2HM_js.d}});Object.defineProperty(exports,"AgentTypes",{enumerable:true,get:function(){return chunkJVHUW2HM_js.e}});Object.defineProperty(exports,"BaseClient",{enumerable:true,get:function(){return chunkJVHUW2HM_js.c}});Object.defineProperty(exports,"FileClient",{enumerable:true,get:function(){return chunkJVHUW2HM_js.f}});Object.defineProperty(exports,"GuardrailClient",{enumerable:true,get:function(){return chunkJVHUW2HM_js.m}});Object.defineProperty(exports,"LangtrainError",{enumerable:true,get:function(){return chunkJVHUW2HM_js.b}});Object.defineProperty(exports,"Langtune",{enumerable:true,get:function(){return chunkJVHUW2HM_js.r}});Object.defineProperty(exports,"Langvision",{enumerable:true,get:function(){return chunkJVHUW2HM_js.q}});Object.defineProperty(exports,"ModelClient",{enumerable:true,get:function(){return chunkJVHUW2HM_js.i}});Object.defineProperty(exports,"ModelTypes",{enumerable:true,get:function(){return chunkJVHUW2HM_js.j}});Object.defineProperty(exports,"SecretClient",{enumerable:true,get:function(){return chunkJVHUW2HM_js.k}});Object.defineProperty(exports,"SecretTypes",{enumerable:true,get:function(){return chunkJVHUW2HM_js.l}});Object.defineProperty(exports,"SubscriptionClient",{enumerable:true,get:function(){return chunkJVHUW2HM_js.h}});Object.defineProperty(exports,"Text",{enumerable:true,get:function(){return chunkJVHUW2HM_js.p}});Object.defineProperty(exports,"TrainingClient",{enumerable:true,get:function(){return chunkJVHUW2HM_js.g}});Object.defineProperty(exports,"UsageClient",{enumerable:true,get:function(){return chunkJVHUW2HM_js.n}});Object.defineProperty(exports,"Vision",{enumerable:true,get:function(){return chunkJVHUW2HM_js.o}});//# sourceMappingURL=index.js.map
2
2
  //# sourceMappingURL=index.js.map
package/dist/index.mjs CHANGED
@@ -1,2 +1,2 @@
1
- export{d as AgentClient,e as AgentTypes,c as BaseClient,f as FileClient,m as GuardrailClient,b as LangtrainError,r as Langtune,q as Langvision,i as ModelClient,j as ModelTypes,k as SecretClient,l as SecretTypes,h as SubscriptionClient,p as Text,g as TrainingClient,n as UsageClient,o as Vision}from'./chunk-WIGKVYUR.mjs';//# sourceMappingURL=index.mjs.map
1
+ export{d as AgentClient,e as AgentTypes,c as BaseClient,f as FileClient,m as GuardrailClient,b as LangtrainError,r as Langtune,q as Langvision,i as ModelClient,j as ModelTypes,k as SecretClient,l as SecretTypes,h as SubscriptionClient,p as Text,g as TrainingClient,n as UsageClient,o as Vision}from'./chunk-CWSKNQE4.mjs';//# sourceMappingURL=index.mjs.map
2
2
  //# sourceMappingURL=index.mjs.map
package/package.json CHANGED
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "name": "langtrain",
3
- "version": "0.2.6",
3
+ "version": "0.2.9",
4
4
  "description": "Unified JavaScript SDK for Langtrain Ecosystem",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",
7
7
  "types": "./dist/index.d.ts",
8
8
  "bin": {
9
- "langtrain": "./dist/cli.js",
10
- "lt": "./dist/cli.js"
9
+ "langtrain": "dist/cli.js",
10
+ "lt": "dist/cli.js"
11
11
  },
12
12
  "scripts": {
13
13
  "build": "tsup",
package/src/cli/auth.ts CHANGED
@@ -55,82 +55,8 @@ export async function ensureAuth(): Promise<string> {
55
55
  * Interactive login — browser-based OAuth flow with API key fallback.
56
56
  */
57
57
  export async function handleLogin() {
58
- const s = spinner();
59
- s.start('Connecting to Langtrain...');
60
-
61
- try {
62
- // 1. Request device code
63
- const { data: codeData } = await axios.post(`${getApiBase()}/auth/device/code`);
64
- const { device_code, user_code, verification_url, expires_in, interval } = codeData;
65
-
66
- s.stop(green('Connected.'));
67
-
68
- console.log('\n ' + bgMagenta(black(' AUTHENTICATION ')) + '\n');
69
- console.log(` To log in, please open your browser to:\n ${cyan(verification_url + '?code=' + user_code)}\n`);
70
-
71
- note(
72
- `Confirmation Code:\n${bold(user_code)}`,
73
- 'Verify in Browser'
74
- );
75
-
76
- console.log(gray(' Opening browser automatically...'));
77
- await openBrowser(`${verification_url}?code=${user_code}`);
78
-
79
- const pollSpinner = spinner();
80
- pollSpinner.start('Waiting for approval in browser...');
81
-
82
- // 2. Poll for token
83
- const startTime = Date.now();
84
- const timeout = expires_in * 1000;
85
-
86
- while (Date.now() - startTime < timeout) {
87
- try {
88
- const { data: tokenData } = await axios.post(`${getApiBase()}/auth/device/token?device_code=${device_code}`);
89
-
90
- if (tokenData.status === 'approved') {
91
- const apiKey = tokenData.api_key;
92
- pollSpinner.stop(green('Approved!'));
93
-
94
- const verifySpinner = spinner();
95
- verifySpinner.start('Verifying credentials...');
96
-
97
- const client = new SubscriptionClient({ apiKey });
98
- const info = await client.getStatus();
99
-
100
- const planBadge = info.plan === 'pro'
101
- ? bgMagenta(black(' PRO '))
102
- : info.plan === 'enterprise'
103
- ? bgMagenta(black(' ENTERPRISE '))
104
- : ' FREE ';
105
-
106
- verifySpinner.stop(green(`Authenticated ${planBadge}`));
107
-
108
- const config = getConfig();
109
- saveConfig({ ...config, apiKey });
110
- console.log(green(' ✔ Credentials saved to ~/.langtrain/config.json\n'));
111
- return;
112
- }
113
-
114
- if (tokenData.status === 'expired') {
115
- pollSpinner.stop(red('Device code expired.'));
116
- break;
117
- }
118
-
119
- // Wait for the requested interval
120
- await new Promise(r => setTimeout(r, interval * 1000));
121
- } catch (err) {
122
- // Ignore network errors during polling
123
- await new Promise(r => setTimeout(r, interval * 1000));
124
- }
125
- }
126
-
127
- pollSpinner.stop(yellow('Login timed out.'));
128
- } catch (err: any) {
129
- s.stop(red('Could not reach Langtrain server.'));
130
- }
131
-
132
- // 3. Fallback to manual entry if browser flow fails
133
- console.log(gray('\n Browser login failed or timed out. Falling back to manual entry.'));
58
+ console.log('\n ' + bgMagenta(black(' AUTHENTICATION ')) + '\n');
59
+ console.log(gray(' To log in, you will need your personal API Key.'));
134
60
 
135
61
  while (true) {
136
62
  console.log(dim(' ─────────────────────────────────────'));
@@ -146,7 +72,7 @@ export async function handleLogin() {
146
72
  });
147
73
 
148
74
  if (isCancel(apiKey)) {
149
- cancel('Operation cancelled');
75
+ cancel('Login cancelled.');
150
76
  process.exit(0);
151
77
  }
152
78
 
@@ -167,10 +93,14 @@ export async function handleLogin() {
167
93
 
168
94
  const config = getConfig();
169
95
  saveConfig({ ...config, apiKey: apiKey as string });
170
- console.log(green(' ✔ Credentials saved to ~/.langtrain/config.json\n'));
96
+ console.log(green(' ✔ Credentials saved locally. You are now logged in!\n'));
171
97
  return;
172
98
  } catch (e: any) {
173
- verifySpinner.stop(red('Invalid API Key. Please try again.'));
99
+ verifySpinner.stop(red('Invalid API Key.'));
100
+ if (e.message) {
101
+ console.log(red(`\n Server Error: ${e.message}`));
102
+ }
103
+ console.log(yellow(' Please ensure your key is valid and you have an active account.\n'));
174
104
  }
175
105
  }
176
106
  }
package/src/lib/base.ts CHANGED
@@ -255,15 +255,17 @@ export abstract class BaseClient {
255
255
  : parsed;
256
256
  }
257
257
 
258
- const message = serverMessage
259
- ? String(serverMessage)
260
- : error.code === 'ECONNABORTED'
261
- ? `Request timed out`
262
- : status === 429
263
- ? `Rate limited${retryAfter ? ` — retry in ${retryAfter}s` : ''}`
264
- : status
265
- ? `API request failed with status ${status}`
266
- : `Network error: ${error.message}`;
258
+ const message = typeof serverMessage === 'object'
259
+ ? JSON.stringify(serverMessage, null, 2)
260
+ : serverMessage
261
+ ? String(serverMessage)
262
+ : error.code === 'ECONNABORTED'
263
+ ? `Request timed out`
264
+ : status === 429
265
+ ? `Rate limited${retryAfter ? ` retry in ${retryAfter}s` : ''}`
266
+ : status
267
+ ? `API request failed with status ${status}`
268
+ : `Network error: ${error.message}`;
267
269
 
268
270
  return new LangtrainError(message, {
269
271
  status,
@@ -282,7 +284,7 @@ export abstract class BaseClient {
282
284
 
283
285
  private log(msg: string): void {
284
286
  if (this.debug) {
285
- process.stderr.write(`[langtrain] ${msg}\n`);
287
+ process.stderr.write(`[cortex] ${msg}\n`);
286
288
  }
287
289
  }
288
290
 
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/lib/base.ts","../src/lib/agent.ts","../src/lib/files.ts","../src/lib/training.ts","../src/lib/subscription.ts","../src/lib/models.ts","../src/lib/secrets.ts","../src/lib/guardrails.ts","../src/lib/usage.ts"],"names":["DEFAULT_BASE_URL","DEFAULT_TIMEOUT","DEFAULT_MAX_RETRIES","DEFAULT_MAX_RPS","RETRYABLE_STATUS_CODES","LangtrainError","message","options","RateLimiter","capacity","refillRate","waitMs","seconds","now","elapsed","ms","resolve","BaseClient","config","maxRps","axios","fn","lastError","attempt","start","result","latencyMs","error","delay","AxiosError","status","headers","data","serverMessage","retryAfter","retryHeader","parsed","msg","event","agent_exports","__export","AgentClient","workspaceId","params","agentId","agent","input","messages","conversationId","limit","FileClient","filePath","purpose","fs","form","FormData","fileId","TrainingClient","job","jobId","SubscriptionClient","feature","models_exports","ModelClient","task","modelId","secrets_exports","SecretClient","key","value","GuardrailClient","guardrailId","datasetId","UsageClient","days"],"mappings":"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","file":"chunk-N6MFB652.js","sourcesContent":["import axios, { AxiosInstance, AxiosError, AxiosRequestConfig, AxiosResponse } from 'axios';\n\n// ── Shared Configuration ───────────────────────────────────────────────────\n\n/** Configuration for all Langtrain SDK clients. */\nexport interface ClientConfig {\n /** Your Langtrain API key. */\n apiKey: string;\n /** Override the default API base URL. */\n baseUrl?: string;\n /** Request timeout in milliseconds (default: 30000). */\n timeout?: number;\n /** Maximum number of retries on transient errors (default: 2). */\n maxRetries?: number;\n /** Max requests per second (client-side rate limiting, default: 10). */\n maxRequestsPerSecond?: number;\n /** Enable debug logging to stderr (default: false). */\n debug?: boolean;\n /** Optional callback invoked on every request for observability. */\n onRequest?: (event: RequestEvent) => void;\n}\n\n/** Emitted for every API request (success or failure). */\nexport interface RequestEvent {\n method: string;\n path: string;\n status?: number;\n latencyMs: number;\n attempt: number;\n error?: LangtrainError;\n rateLimitRemaining?: number;\n rateLimitReset?: number;\n}\n\nconst DEFAULT_BASE_URL = 'https://api.langtrain.xyz/v1';\nconst DEFAULT_TIMEOUT = 30_000;\nconst DEFAULT_MAX_RETRIES = 2;\nconst DEFAULT_MAX_RPS = 10;\nconst RETRYABLE_STATUS_CODES = [408, 429, 500, 502, 503, 504];\n\n// ── Custom Error ───────────────────────────────────────────────────────────\n\nexport class LangtrainError extends Error {\n /** HTTP status code, if available. */\n readonly status?: number;\n /** Raw error code from the API. */\n readonly code?: string;\n /** The original error, if any. */\n readonly cause?: Error;\n /** Seconds until rate limit resets (from Retry-After header). */\n readonly retryAfter?: number;\n\n constructor(message: string, options?: {\n status?: number;\n code?: string;\n cause?: Error;\n retryAfter?: number;\n }) {\n super(message);\n this.name = 'LangtrainError';\n this.status = options?.status;\n this.code = options?.code;\n this.cause = options?.cause;\n this.retryAfter = options?.retryAfter;\n }\n\n /** True if the error was a network/timeout issue (retryable). */\n get isTransient(): boolean {\n return this.code === 'ECONNABORTED' || this.code === 'NETWORK_ERROR' ||\n (this.status !== undefined && RETRYABLE_STATUS_CODES.includes(this.status));\n }\n\n /** True if the API key was invalid or expired. */\n get isAuthError(): boolean {\n return this.status === 401 || this.status === 403;\n }\n\n /** True if a resource was not found. */\n get isNotFound(): boolean {\n return this.status === 404;\n }\n\n /** True if rate-limited. */\n get isRateLimited(): boolean {\n return this.status === 429;\n }\n}\n\n// ── Token Bucket Rate Limiter ──────────────────────────────────────────────\n\n/**\n * Simple token-bucket rate limiter.\n * Allows bursting up to `capacity` requests, refills at `refillRate` tokens/sec.\n */\nclass RateLimiter {\n private tokens: number;\n private lastRefill: number;\n\n constructor(\n private readonly capacity: number,\n private readonly refillRate: number,\n ) {\n this.tokens = capacity;\n this.lastRefill = Date.now();\n }\n\n /** Wait until a token is available, then consume it. */\n async acquire(): Promise<void> {\n this.refill();\n\n if (this.tokens >= 1) {\n this.tokens -= 1;\n return;\n }\n\n // Wait for next token\n const waitMs = ((1 - this.tokens) / this.refillRate) * 1000;\n await this.sleep(Math.ceil(waitMs));\n this.refill();\n this.tokens -= 1;\n }\n\n /** Pause for `seconds` (e.g. from Retry-After header). */\n async waitFor(seconds: number): Promise<void> {\n await this.sleep(seconds * 1000);\n }\n\n private refill(): void {\n const now = Date.now();\n const elapsed = (now - this.lastRefill) / 1000;\n this.tokens = Math.min(this.capacity, this.tokens + elapsed * this.refillRate);\n this.lastRefill = now;\n }\n\n private sleep(ms: number): Promise<void> {\n return new Promise(resolve => setTimeout(resolve, ms));\n }\n}\n\n// ── Base Client ────────────────────────────────────────────────────────────\n\n/**\n * BaseClient — abstract foundation for all Langtrain SDK clients.\n *\n * Features:\n * - Shared axios instance with API key auth\n * - Configurable timeouts\n * - Automatic retry with exponential backoff on transient errors\n * - Client-side token-bucket rate limiting\n * - Retry-After header respect on 429s\n * - Structured error wrapping (LangtrainError)\n * - Debug logging and request event hooks\n */\nexport abstract class BaseClient {\n protected readonly http: AxiosInstance;\n protected readonly maxRetries: number;\n private readonly rateLimiter: RateLimiter;\n private readonly debug: boolean;\n private readonly onRequest?: (event: RequestEvent) => void;\n\n constructor(config: ClientConfig) {\n this.maxRetries = config.maxRetries ?? DEFAULT_MAX_RETRIES;\n this.debug = config.debug ?? false;\n this.onRequest = config.onRequest;\n\n const maxRps = config.maxRequestsPerSecond ?? DEFAULT_MAX_RPS;\n this.rateLimiter = new RateLimiter(maxRps, maxRps);\n\n this.http = axios.create({\n baseURL: config.baseUrl || DEFAULT_BASE_URL,\n timeout: config.timeout ?? DEFAULT_TIMEOUT,\n headers: {\n 'X-API-Key': config.apiKey,\n 'Content-Type': 'application/json',\n 'User-Agent': 'langtrain-sdk/0.2.x',\n },\n });\n }\n\n /**\n * Execute a request with rate limiting, automatic retry, and error wrapping.\n */\n protected async request<T>(fn: () => Promise<T>): Promise<T> {\n let lastError: LangtrainError | undefined;\n\n for (let attempt = 0; attempt <= this.maxRetries; attempt++) {\n // Acquire a rate limiter token before each attempt\n await this.rateLimiter.acquire();\n\n const start = Date.now();\n\n try {\n const result = await fn();\n const latencyMs = Date.now() - start;\n\n this.log(`✓ request succeeded (${latencyMs}ms, attempt ${attempt + 1})`);\n this.emitEvent({ method: '', path: '', status: 200, latencyMs, attempt });\n\n return result;\n } catch (error) {\n const latencyMs = Date.now() - start;\n lastError = this.wrapError(error);\n\n this.log(`✗ request failed: ${lastError.message} (${latencyMs}ms, attempt ${attempt + 1})`);\n this.emitEvent({\n method: '', path: '',\n status: lastError.status,\n latencyMs,\n attempt,\n error: lastError,\n rateLimitRemaining: lastError.isRateLimited ? 0 : undefined,\n rateLimitReset: lastError.retryAfter,\n });\n\n // Don't retry non-transient errors or on last attempt\n if (!lastError.isTransient || attempt === this.maxRetries) {\n throw lastError;\n }\n\n // If rate-limited with Retry-After, respect it\n if (lastError.isRateLimited && lastError.retryAfter) {\n this.log(`⏳ rate limited, waiting ${lastError.retryAfter}s (Retry-After)`);\n await this.rateLimiter.waitFor(lastError.retryAfter);\n } else {\n // Exponential backoff: 500ms, 1000ms, 2000ms...\n const delay = Math.min(500 * Math.pow(2, attempt), 5000);\n this.log(`↻ retrying in ${delay}ms...`);\n await this.sleep(delay);\n }\n }\n }\n\n throw lastError!;\n }\n\n /**\n * Wrap any thrown error into a structured LangtrainError.\n */\n private wrapError(error: unknown): LangtrainError {\n if (error instanceof LangtrainError) return error;\n\n if (error instanceof AxiosError) {\n const status = error.response?.status;\n const headers = error.response?.headers;\n const data = error.response?.data as Record<string, unknown> | undefined;\n const serverMessage = data?.detail ?? data?.message ?? data?.error;\n\n // Parse Retry-After header (seconds or HTTP date)\n let retryAfter: number | undefined;\n const retryHeader = headers?.['retry-after'];\n if (retryHeader) {\n const parsed = Number(retryHeader);\n retryAfter = isNaN(parsed)\n ? Math.max(0, Math.ceil((new Date(retryHeader).getTime() - Date.now()) / 1000))\n : parsed;\n }\n\n const message = serverMessage\n ? String(serverMessage)\n : error.code === 'ECONNABORTED'\n ? `Request timed out`\n : status === 429\n ? `Rate limited${retryAfter ? ` — retry in ${retryAfter}s` : ''}`\n : status\n ? `API request failed with status ${status}`\n : `Network error: ${error.message}`;\n\n return new LangtrainError(message, {\n status,\n code: error.code,\n cause: error,\n retryAfter,\n });\n }\n\n if (error instanceof Error) {\n return new LangtrainError(error.message, { cause: error });\n }\n\n return new LangtrainError(String(error));\n }\n\n private log(msg: string): void {\n if (this.debug) {\n process.stderr.write(`[langtrain] ${msg}\\n`);\n }\n }\n\n private emitEvent(event: RequestEvent): void {\n if (this.onRequest) {\n try {\n this.onRequest(event);\n } catch {\n // Never let user callbacks crash the SDK\n }\n }\n }\n\n private sleep(ms: number): Promise<void> {\n return new Promise(resolve => setTimeout(resolve, ms));\n }\n}\n","import { BaseClient, ClientConfig } from './base';\n\n// ── Types ──────────────────────────────────────────────────────────────────\n\nexport interface Agent {\n id: string;\n workspace_id: string;\n name: string;\n description?: string;\n model_id?: string;\n config: AgentConfig;\n is_active: boolean;\n created_at: string;\n updated_at: string;\n}\n\nexport interface AgentConfig {\n system_prompt?: string;\n temperature?: number;\n max_tokens?: number;\n tools?: string[];\n [key: string]: unknown;\n}\n\nexport interface AgentCreate {\n workspace_id: string;\n name: string;\n description?: string;\n model_id?: string;\n config?: AgentConfig;\n}\n\nexport interface AgentRun {\n id: string;\n conversation_id: string;\n success: boolean;\n output?: unknown;\n error?: string;\n latency_ms: number;\n tokens_used: number;\n}\n\n// ── Client ─────────────────────────────────────────────────────────────────\n\n/**\n * Client for managing AI agents — create, execute, and monitor.\n *\n * @example\n * ```ts\n * const agents = new AgentClient({ apiKey: 'lt_...' });\n * const list = await agents.list();\n * const result = await agents.execute(list[0].id, 'Hello!');\n * ```\n */\nexport class AgentClient extends BaseClient {\n constructor(config: ClientConfig) {\n super(config);\n }\n\n /** List all agents, optionally filtered by workspace. */\n async list(workspaceId?: string): Promise<Agent[]> {\n return this.request(async () => {\n const params: Record<string, string> = {};\n if (workspaceId) params.workspace_id = workspaceId;\n const res = await this.http.get<{ agents: Agent[] }>('/agents', { params });\n return res.data.agents;\n });\n }\n\n /** Get a single agent by ID. */\n async get(agentId: string): Promise<Agent> {\n return this.request(async () => {\n const res = await this.http.get<Agent>(`/agents/${agentId}`);\n return res.data;\n });\n }\n\n /** Create a new agent. */\n async create(agent: AgentCreate): Promise<Agent> {\n return this.request(async () => {\n const res = await this.http.post<Agent>('/agents/', agent);\n return res.data;\n });\n }\n\n /** Delete an agent by ID. */\n async delete(agentId: string): Promise<void> {\n return this.request(async () => {\n await this.http.delete(`/agents/${agentId}`);\n });\n }\n\n /** Execute an agent with input and optional conversation context. */\n async execute(agentId: string, input: string, messages: Array<{ role: string; content: string }> = [], conversationId?: string): Promise<AgentRun> {\n return this.request(async () => {\n const res = await this.http.post<AgentRun>(`/agents/${agentId}/execute`, {\n input,\n messages,\n conversation_id: conversationId,\n });\n return res.data;\n });\n }\n\n /** Fetch recent logs for an agent. */\n async logs(agentId: string, limit: number = 100): Promise<string[]> {\n return this.request(async () => {\n const res = await this.http.get<{ logs: string[] }>(`/agents/${agentId}/logs`, {\n params: { limit },\n });\n return res.data.logs;\n });\n }\n}\n","import { BaseClient, ClientConfig } from './base';\nimport FormData from 'form-data';\nimport fs from 'fs';\n\n// ── Types ──────────────────────────────────────────────────────────────────\n\nexport interface FileResponse {\n id: string;\n filename: string;\n purpose: string;\n bytes: number;\n created_at: string;\n}\n\n// ── Client ─────────────────────────────────────────────────────────────────\n\n/**\n * Client for managing file uploads (datasets for fine-tuning).\n *\n * @example\n * ```ts\n * const files = new FileClient({ apiKey: 'lt_...' });\n * const uploaded = await files.upload('./data.jsonl');\n * ```\n */\nexport class FileClient extends BaseClient {\n constructor(config: ClientConfig) {\n super(config);\n }\n\n /** Upload a file from a local path. */\n async upload(filePath: string, workspaceId?: string, purpose: string = 'fine-tune'): Promise<FileResponse> {\n if (!fs.existsSync(filePath)) {\n throw new Error(`File not found: ${filePath}`);\n }\n\n return this.request(async () => {\n const form = new FormData();\n form.append('file', fs.createReadStream(filePath));\n if (workspaceId) form.append('workspace_id', workspaceId);\n form.append('purpose', purpose);\n\n const res = await this.http.post<FileResponse>('/files', form, {\n headers: form.getHeaders(),\n maxContentLength: Infinity,\n maxBodyLength: Infinity,\n });\n return res.data;\n });\n }\n\n /** List files in a workspace, optionally filtered by purpose. */\n async list(workspaceId: string, purpose?: string): Promise<FileResponse[]> {\n return this.request(async () => {\n const params: Record<string, string> = { workspace_id: workspaceId };\n if (purpose) params.purpose = purpose;\n const res = await this.http.get<{ data: FileResponse[] }>('/files', { params });\n return res.data.data;\n });\n }\n\n /** Delete a file by ID. */\n async delete(fileId: string): Promise<void> {\n return this.request(async () => {\n await this.http.delete(`/files/${fileId}`);\n });\n }\n}\n","import { BaseClient, ClientConfig } from './base';\n\n// ── Types ──────────────────────────────────────────────────────────────────\n\nexport interface FineTuneHyperparameters {\n epochs?: number;\n learning_rate?: number;\n batch_size?: number;\n warmup_steps?: number;\n lora_rank?: number;\n lora_alpha?: number;\n weight_decay?: number;\n}\n\nexport interface FineTuneJobCreate {\n name?: string;\n base_model: string;\n model_id?: string;\n dataset_id: string;\n guardrail_id?: string;\n task?: 'text' | 'vision';\n training_method?: 'sft' | 'dpo' | 'rlhf' | 'lora' | 'qlora';\n hyperparameters?: FineTuneHyperparameters;\n}\n\nexport interface FineTuneJobResponse {\n id: string;\n name: string;\n status: 'pending' | 'running' | 'completed' | 'failed' | 'cancelled';\n progress: number;\n error_message?: string;\n base_model?: string;\n training_method?: string;\n created_at: string;\n started_at?: string;\n completed_at?: string;\n}\n\nexport interface FineTuneJobList {\n data: FineTuneJobResponse[];\n has_more: boolean;\n}\n\n// ── Client ─────────────────────────────────────────────────────────────────\n\n/**\n * Client for managing fine-tuning training jobs.\n *\n * @example\n * ```ts\n * const training = new TrainingClient({ apiKey: 'lt_...' });\n * const job = await training.createJob({\n * base_model: 'meta-llama/Llama-3.1-8B',\n * dataset_id: 'file_abc123',\n * training_method: 'lora',\n * });\n * ```\n */\nexport class TrainingClient extends BaseClient {\n constructor(config: ClientConfig) {\n super(config);\n }\n\n /** Create a new fine-tuning job. */\n async createJob(job: FineTuneJobCreate): Promise<FineTuneJobResponse> {\n return this.request(async () => {\n const res = await this.http.post<FineTuneJobResponse>('/finetune/jobs', job);\n return res.data;\n });\n }\n\n /** List fine-tuning jobs for a workspace. */\n async listJobs(workspaceId: string, limit: number = 10): Promise<FineTuneJobList> {\n return this.request(async () => {\n const res = await this.http.get<FineTuneJobList>('/finetune/jobs', {\n params: { workspace_id: workspaceId, limit },\n });\n return res.data;\n });\n }\n\n /** Get a specific job by ID. */\n async getJob(jobId: string): Promise<FineTuneJobResponse> {\n return this.request(async () => {\n const res = await this.http.get<FineTuneJobResponse>(`/finetune/jobs/${jobId}`);\n return res.data;\n });\n }\n\n /** Cancel a running job. */\n async cancelJob(jobId: string): Promise<FineTuneJobResponse> {\n return this.request(async () => {\n const res = await this.http.post<FineTuneJobResponse>(`/finetune/jobs/${jobId}/cancel`);\n return res.data;\n });\n }\n}\n","import { BaseClient, ClientConfig } from './base';\n\n// ── Types ──────────────────────────────────────────────────────────────────\n\nexport interface SubscriptionInfo {\n is_active: boolean;\n plan: string;\n plan_name: string;\n expires_at?: string;\n features: string[];\n limits: Record<string, number>;\n usage?: {\n tokensUsedThisMonth?: number;\n tokenLimit?: number;\n apiCalls?: number;\n };\n}\n\nexport interface FeatureCheck {\n feature: string;\n allowed: boolean;\n limit?: number;\n used?: number;\n}\n\n// ── Client ─────────────────────────────────────────────────────────────────\n\n/**\n * Client for checking subscription status and feature access.\n *\n * @example\n * ```ts\n * const sub = new SubscriptionClient({ apiKey: 'lt_...' });\n * const status = await sub.getStatus();\n * console.log(status.plan); // 'pro'\n * ```\n */\nexport class SubscriptionClient extends BaseClient {\n constructor(config: ClientConfig) {\n super(config);\n }\n\n /** Get current subscription status. */\n async getStatus(): Promise<SubscriptionInfo> {\n return this.request(async () => {\n const res = await this.http.get<SubscriptionInfo>('/subscription/status');\n return res.data;\n });\n }\n\n /** Check if a specific feature is available on the current plan. */\n async checkFeature(feature: string): Promise<FeatureCheck> {\n return this.request(async () => {\n const res = await this.http.get<FeatureCheck>(`/subscription/check/${feature}`);\n return res.data;\n });\n }\n\n /** Get usage analytics for the current subscription. */\n async getLimits(): Promise<Record<string, unknown>> {\n return this.request(async () => {\n const res = await this.http.get('/subscription/analytics');\n return res.data;\n });\n }\n}\n","import { BaseClient, ClientConfig } from './base';\n\n// ── Types ──────────────────────────────────────────────────────────────────\n\nexport interface Permission {\n id: string;\n object: string;\n created: number;\n allow_create_engine: boolean;\n allow_sampling: boolean;\n allow_logprobs: boolean;\n allow_search_indices: boolean;\n allow_view: boolean;\n allow_fine_tuning: boolean;\n organization: string;\n group: string | null;\n is_blocking: boolean;\n}\n\nexport interface Model {\n id: string;\n object: string;\n created: number;\n owned_by: string;\n permission: Permission[];\n root: string;\n parent: string | null;\n task?: 'text' | 'vision' | 'agent';\n}\n\n// ── Client ─────────────────────────────────────────────────────────────────\n\n/**\n * Client for browsing available base models.\n *\n * @example\n * ```ts\n * const models = new ModelClient({ apiKey: 'lt_...' });\n * const all = await models.list();\n * const textModels = await models.list('text');\n * ```\n */\nexport class ModelClient extends BaseClient {\n constructor(config: ClientConfig) {\n super(config);\n }\n\n /** List available models, optionally filtered by task type. */\n async list(task?: 'text' | 'vision' | 'agent'): Promise<Model[]> {\n return this.request(async () => {\n const params: Record<string, string> = {};\n if (task) params.task = task;\n const res = await this.http.get<{ data: Model[] }>('/models', { params });\n return res.data.data;\n });\n }\n\n /** Get a specific model by ID. */\n async get(modelId: string): Promise<Model> {\n return this.request(async () => {\n const res = await this.http.get<Model>(`/models/${modelId}`);\n return res.data;\n });\n }\n}\n","import { BaseClient, ClientConfig } from './base';\n\n// ── Types ──────────────────────────────────────────────────────────────────\n\nexport interface Secret {\n key: string;\n created_at: string;\n updated_at: string;\n}\n\n// ── Client ─────────────────────────────────────────────────────────────────\n\n/**\n * Client for managing workspace secrets and environment variables.\n *\n * @example\n * ```ts\n * const secrets = new SecretClient({ apiKey: 'lt_...' });\n * await secrets.set('OPENAI_KEY', 'sk-...');\n * const all = await secrets.list();\n * ```\n */\nexport class SecretClient extends BaseClient {\n constructor(config: ClientConfig) {\n super(config);\n }\n\n /** List all secrets in a workspace. Values are redacted. */\n async list(workspaceId?: string): Promise<Secret[]> {\n return this.request(async () => {\n const params: Record<string, string> = {};\n if (workspaceId) params.workspace_id = workspaceId;\n const res = await this.http.get<{ secrets: Secret[] }>('/secrets', { params });\n return res.data.secrets;\n });\n }\n\n /** Set (create or update) a secret. */\n async set(key: string, value: string, workspaceId?: string): Promise<Secret> {\n return this.request(async () => {\n const res = await this.http.post<Secret>('/secrets', { key, value, workspace_id: workspaceId });\n return res.data;\n });\n }\n\n /** Delete a secret by key. */\n async delete(key: string, workspaceId?: string): Promise<void> {\n return this.request(async () => {\n const params: Record<string, string> = {};\n if (workspaceId) params.workspace_id = workspaceId;\n await this.http.delete(`/secrets/${key}`, { params });\n });\n }\n}\n","import { BaseClient, ClientConfig } from './base';\n\n// ── Types ──────────────────────────────────────────────────────────────────\n\nexport interface GuardrailConfig {\n pii_enabled: boolean;\n pii_entities?: string[];\n profanity_enabled: boolean;\n profanity_threshold?: number;\n blocked_topics?: string[];\n regex_patterns?: string[];\n min_length?: number;\n max_length?: number;\n}\n\nexport interface Guardrail {\n id: string;\n workspace_id: string;\n name: string;\n description?: string;\n config: GuardrailConfig;\n is_active: boolean;\n created_at: string;\n updated_at: string;\n}\n\nexport interface GuardrailCreate {\n name: string;\n description?: string;\n config: GuardrailConfig;\n}\n\nexport interface GuardrailApplyResult {\n total_rows: number;\n passed: number;\n failed: number;\n violations: Array<{ row: number; rule: string; message: string }>;\n}\n\n// ── Client ─────────────────────────────────────────────────────────────────\n\n/**\n * Client for managing data guardrails (PII, profanity, length, regex).\n *\n * @example\n * ```ts\n * const guardrails = new GuardrailClient({ apiKey: 'lt_...' });\n * const rule = await guardrails.create({\n * name: 'PII Filter',\n * config: { pii_enabled: true, profanity_enabled: false },\n * });\n * ```\n */\nexport class GuardrailClient extends BaseClient {\n constructor(config: ClientConfig) {\n super(config);\n }\n\n /** List guardrails, optionally filtered by workspace. */\n async list(workspaceId?: string): Promise<Guardrail[]> {\n return this.request(async () => {\n const params: Record<string, string> = {};\n if (workspaceId) params.workspace_id = workspaceId;\n const res = await this.http.get<Guardrail[]>('/guardrails/', { params });\n return res.data;\n });\n }\n\n /** Get a guardrail by ID. */\n async get(guardrailId: string): Promise<Guardrail> {\n return this.request(async () => {\n const res = await this.http.get<Guardrail>(`/guardrails/${guardrailId}`);\n return res.data;\n });\n }\n\n /** Create a new guardrail. */\n async create(data: GuardrailCreate): Promise<Guardrail> {\n return this.request(async () => {\n const res = await this.http.post<Guardrail>('/guardrails/', data);\n return res.data;\n });\n }\n\n /** Delete a guardrail by ID. */\n async delete(guardrailId: string): Promise<void> {\n return this.request(async () => {\n await this.http.delete(`/guardrails/${guardrailId}`);\n });\n }\n\n /** Apply a guardrail to a dataset for validation. */\n async apply(datasetId: string, guardrailId: string): Promise<GuardrailApplyResult> {\n return this.request(async () => {\n const res = await this.http.post<GuardrailApplyResult>('/guardrails/apply', {\n dataset_id: datasetId,\n guardrail_id: guardrailId,\n });\n return res.data;\n });\n }\n}\n","import { BaseClient, ClientConfig } from './base';\n\n// ── Types ──────────────────────────────────────────────────────────────────\n\nexport interface UsageSummary {\n workspace_id: string;\n plan: string;\n quotas: Record<string, number>;\n billing?: {\n plan_id: string;\n tokens_used: number;\n tokens_limit: number;\n period_end: string;\n };\n}\n\nexport interface UsageHistoryPoint {\n date: string;\n tokens: number;\n agent_runs: number;\n cost: number;\n}\n\n// ── Client ─────────────────────────────────────────────────────────────────\n\n/**\n * Client for querying usage metrics and billing data.\n *\n * @example\n * ```ts\n * const usage = new UsageClient({ apiKey: 'lt_...' });\n * const summary = await usage.getSummary('ws_abc123');\n * console.log(summary.billing?.tokens_used);\n * ```\n */\nexport class UsageClient extends BaseClient {\n constructor(config: ClientConfig) {\n super(config);\n }\n\n /** Get current usage summary for a workspace. */\n async getSummary(workspaceId: string): Promise<UsageSummary> {\n return this.request(async () => {\n const res = await this.http.get<UsageSummary>('/usage', {\n params: { workspace_id: workspaceId },\n });\n return res.data;\n });\n }\n\n /** Get historical usage data for charts. */\n async getHistory(workspaceId: string, days: number = 30): Promise<UsageHistoryPoint[]> {\n return this.request(async () => {\n const res = await this.http.get<{ history: UsageHistoryPoint[] }>('/usage/history', {\n params: { workspace_id: workspaceId, days },\n });\n return res.data.history;\n });\n }\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/lib/base.ts","../src/lib/agent.ts","../src/lib/files.ts","../src/lib/training.ts","../src/lib/subscription.ts","../src/lib/models.ts","../src/lib/secrets.ts","../src/lib/guardrails.ts","../src/lib/usage.ts"],"names":["DEFAULT_BASE_URL","DEFAULT_TIMEOUT","DEFAULT_MAX_RETRIES","DEFAULT_MAX_RPS","RETRYABLE_STATUS_CODES","LangtrainError","message","options","RateLimiter","capacity","refillRate","waitMs","seconds","now","elapsed","ms","resolve","BaseClient","config","maxRps","axios","fn","lastError","attempt","start","result","latencyMs","error","delay","AxiosError","status","headers","data","serverMessage","retryAfter","retryHeader","parsed","msg","event","agent_exports","__export","AgentClient","workspaceId","params","agentId","agent","input","messages","conversationId","limit","FileClient","filePath","purpose","fs","form","FormData","fileId","TrainingClient","job","jobId","SubscriptionClient","feature","models_exports","ModelClient","task","modelId","secrets_exports","SecretClient","key","value","GuardrailClient","guardrailId","datasetId","UsageClient","days"],"mappings":"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","file":"chunk-WIGKVYUR.mjs","sourcesContent":["import axios, { AxiosInstance, AxiosError, AxiosRequestConfig, AxiosResponse } from 'axios';\n\n// ── Shared Configuration ───────────────────────────────────────────────────\n\n/** Configuration for all Langtrain SDK clients. */\nexport interface ClientConfig {\n /** Your Langtrain API key. */\n apiKey: string;\n /** Override the default API base URL. */\n baseUrl?: string;\n /** Request timeout in milliseconds (default: 30000). */\n timeout?: number;\n /** Maximum number of retries on transient errors (default: 2). */\n maxRetries?: number;\n /** Max requests per second (client-side rate limiting, default: 10). */\n maxRequestsPerSecond?: number;\n /** Enable debug logging to stderr (default: false). */\n debug?: boolean;\n /** Optional callback invoked on every request for observability. */\n onRequest?: (event: RequestEvent) => void;\n}\n\n/** Emitted for every API request (success or failure). */\nexport interface RequestEvent {\n method: string;\n path: string;\n status?: number;\n latencyMs: number;\n attempt: number;\n error?: LangtrainError;\n rateLimitRemaining?: number;\n rateLimitReset?: number;\n}\n\nconst DEFAULT_BASE_URL = 'https://api.langtrain.xyz/v1';\nconst DEFAULT_TIMEOUT = 30_000;\nconst DEFAULT_MAX_RETRIES = 2;\nconst DEFAULT_MAX_RPS = 10;\nconst RETRYABLE_STATUS_CODES = [408, 429, 500, 502, 503, 504];\n\n// ── Custom Error ───────────────────────────────────────────────────────────\n\nexport class LangtrainError extends Error {\n /** HTTP status code, if available. */\n readonly status?: number;\n /** Raw error code from the API. */\n readonly code?: string;\n /** The original error, if any. */\n readonly cause?: Error;\n /** Seconds until rate limit resets (from Retry-After header). */\n readonly retryAfter?: number;\n\n constructor(message: string, options?: {\n status?: number;\n code?: string;\n cause?: Error;\n retryAfter?: number;\n }) {\n super(message);\n this.name = 'LangtrainError';\n this.status = options?.status;\n this.code = options?.code;\n this.cause = options?.cause;\n this.retryAfter = options?.retryAfter;\n }\n\n /** True if the error was a network/timeout issue (retryable). */\n get isTransient(): boolean {\n return this.code === 'ECONNABORTED' || this.code === 'NETWORK_ERROR' ||\n (this.status !== undefined && RETRYABLE_STATUS_CODES.includes(this.status));\n }\n\n /** True if the API key was invalid or expired. */\n get isAuthError(): boolean {\n return this.status === 401 || this.status === 403;\n }\n\n /** True if a resource was not found. */\n get isNotFound(): boolean {\n return this.status === 404;\n }\n\n /** True if rate-limited. */\n get isRateLimited(): boolean {\n return this.status === 429;\n }\n}\n\n// ── Token Bucket Rate Limiter ──────────────────────────────────────────────\n\n/**\n * Simple token-bucket rate limiter.\n * Allows bursting up to `capacity` requests, refills at `refillRate` tokens/sec.\n */\nclass RateLimiter {\n private tokens: number;\n private lastRefill: number;\n\n constructor(\n private readonly capacity: number,\n private readonly refillRate: number,\n ) {\n this.tokens = capacity;\n this.lastRefill = Date.now();\n }\n\n /** Wait until a token is available, then consume it. */\n async acquire(): Promise<void> {\n this.refill();\n\n if (this.tokens >= 1) {\n this.tokens -= 1;\n return;\n }\n\n // Wait for next token\n const waitMs = ((1 - this.tokens) / this.refillRate) * 1000;\n await this.sleep(Math.ceil(waitMs));\n this.refill();\n this.tokens -= 1;\n }\n\n /** Pause for `seconds` (e.g. from Retry-After header). */\n async waitFor(seconds: number): Promise<void> {\n await this.sleep(seconds * 1000);\n }\n\n private refill(): void {\n const now = Date.now();\n const elapsed = (now - this.lastRefill) / 1000;\n this.tokens = Math.min(this.capacity, this.tokens + elapsed * this.refillRate);\n this.lastRefill = now;\n }\n\n private sleep(ms: number): Promise<void> {\n return new Promise(resolve => setTimeout(resolve, ms));\n }\n}\n\n// ── Base Client ────────────────────────────────────────────────────────────\n\n/**\n * BaseClient — abstract foundation for all Langtrain SDK clients.\n *\n * Features:\n * - Shared axios instance with API key auth\n * - Configurable timeouts\n * - Automatic retry with exponential backoff on transient errors\n * - Client-side token-bucket rate limiting\n * - Retry-After header respect on 429s\n * - Structured error wrapping (LangtrainError)\n * - Debug logging and request event hooks\n */\nexport abstract class BaseClient {\n protected readonly http: AxiosInstance;\n protected readonly maxRetries: number;\n private readonly rateLimiter: RateLimiter;\n private readonly debug: boolean;\n private readonly onRequest?: (event: RequestEvent) => void;\n\n constructor(config: ClientConfig) {\n this.maxRetries = config.maxRetries ?? DEFAULT_MAX_RETRIES;\n this.debug = config.debug ?? false;\n this.onRequest = config.onRequest;\n\n const maxRps = config.maxRequestsPerSecond ?? DEFAULT_MAX_RPS;\n this.rateLimiter = new RateLimiter(maxRps, maxRps);\n\n this.http = axios.create({\n baseURL: config.baseUrl || DEFAULT_BASE_URL,\n timeout: config.timeout ?? DEFAULT_TIMEOUT,\n headers: {\n 'X-API-Key': config.apiKey,\n 'Content-Type': 'application/json',\n 'User-Agent': 'langtrain-sdk/0.2.x',\n },\n });\n }\n\n /**\n * Execute a request with rate limiting, automatic retry, and error wrapping.\n */\n protected async request<T>(fn: () => Promise<T>): Promise<T> {\n let lastError: LangtrainError | undefined;\n\n for (let attempt = 0; attempt <= this.maxRetries; attempt++) {\n // Acquire a rate limiter token before each attempt\n await this.rateLimiter.acquire();\n\n const start = Date.now();\n\n try {\n const result = await fn();\n const latencyMs = Date.now() - start;\n\n this.log(`✓ request succeeded (${latencyMs}ms, attempt ${attempt + 1})`);\n this.emitEvent({ method: '', path: '', status: 200, latencyMs, attempt });\n\n return result;\n } catch (error) {\n const latencyMs = Date.now() - start;\n lastError = this.wrapError(error);\n\n this.log(`✗ request failed: ${lastError.message} (${latencyMs}ms, attempt ${attempt + 1})`);\n this.emitEvent({\n method: '', path: '',\n status: lastError.status,\n latencyMs,\n attempt,\n error: lastError,\n rateLimitRemaining: lastError.isRateLimited ? 0 : undefined,\n rateLimitReset: lastError.retryAfter,\n });\n\n // Don't retry non-transient errors or on last attempt\n if (!lastError.isTransient || attempt === this.maxRetries) {\n throw lastError;\n }\n\n // If rate-limited with Retry-After, respect it\n if (lastError.isRateLimited && lastError.retryAfter) {\n this.log(`⏳ rate limited, waiting ${lastError.retryAfter}s (Retry-After)`);\n await this.rateLimiter.waitFor(lastError.retryAfter);\n } else {\n // Exponential backoff: 500ms, 1000ms, 2000ms...\n const delay = Math.min(500 * Math.pow(2, attempt), 5000);\n this.log(`↻ retrying in ${delay}ms...`);\n await this.sleep(delay);\n }\n }\n }\n\n throw lastError!;\n }\n\n /**\n * Wrap any thrown error into a structured LangtrainError.\n */\n private wrapError(error: unknown): LangtrainError {\n if (error instanceof LangtrainError) return error;\n\n if (error instanceof AxiosError) {\n const status = error.response?.status;\n const headers = error.response?.headers;\n const data = error.response?.data as Record<string, unknown> | undefined;\n const serverMessage = data?.detail ?? data?.message ?? data?.error;\n\n // Parse Retry-After header (seconds or HTTP date)\n let retryAfter: number | undefined;\n const retryHeader = headers?.['retry-after'];\n if (retryHeader) {\n const parsed = Number(retryHeader);\n retryAfter = isNaN(parsed)\n ? Math.max(0, Math.ceil((new Date(retryHeader).getTime() - Date.now()) / 1000))\n : parsed;\n }\n\n const message = serverMessage\n ? String(serverMessage)\n : error.code === 'ECONNABORTED'\n ? `Request timed out`\n : status === 429\n ? `Rate limited${retryAfter ? ` — retry in ${retryAfter}s` : ''}`\n : status\n ? `API request failed with status ${status}`\n : `Network error: ${error.message}`;\n\n return new LangtrainError(message, {\n status,\n code: error.code,\n cause: error,\n retryAfter,\n });\n }\n\n if (error instanceof Error) {\n return new LangtrainError(error.message, { cause: error });\n }\n\n return new LangtrainError(String(error));\n }\n\n private log(msg: string): void {\n if (this.debug) {\n process.stderr.write(`[langtrain] ${msg}\\n`);\n }\n }\n\n private emitEvent(event: RequestEvent): void {\n if (this.onRequest) {\n try {\n this.onRequest(event);\n } catch {\n // Never let user callbacks crash the SDK\n }\n }\n }\n\n private sleep(ms: number): Promise<void> {\n return new Promise(resolve => setTimeout(resolve, ms));\n }\n}\n","import { BaseClient, ClientConfig } from './base';\n\n// ── Types ──────────────────────────────────────────────────────────────────\n\nexport interface Agent {\n id: string;\n workspace_id: string;\n name: string;\n description?: string;\n model_id?: string;\n config: AgentConfig;\n is_active: boolean;\n created_at: string;\n updated_at: string;\n}\n\nexport interface AgentConfig {\n system_prompt?: string;\n temperature?: number;\n max_tokens?: number;\n tools?: string[];\n [key: string]: unknown;\n}\n\nexport interface AgentCreate {\n workspace_id: string;\n name: string;\n description?: string;\n model_id?: string;\n config?: AgentConfig;\n}\n\nexport interface AgentRun {\n id: string;\n conversation_id: string;\n success: boolean;\n output?: unknown;\n error?: string;\n latency_ms: number;\n tokens_used: number;\n}\n\n// ── Client ─────────────────────────────────────────────────────────────────\n\n/**\n * Client for managing AI agents — create, execute, and monitor.\n *\n * @example\n * ```ts\n * const agents = new AgentClient({ apiKey: 'lt_...' });\n * const list = await agents.list();\n * const result = await agents.execute(list[0].id, 'Hello!');\n * ```\n */\nexport class AgentClient extends BaseClient {\n constructor(config: ClientConfig) {\n super(config);\n }\n\n /** List all agents, optionally filtered by workspace. */\n async list(workspaceId?: string): Promise<Agent[]> {\n return this.request(async () => {\n const params: Record<string, string> = {};\n if (workspaceId) params.workspace_id = workspaceId;\n const res = await this.http.get<{ agents: Agent[] }>('/agents', { params });\n return res.data.agents;\n });\n }\n\n /** Get a single agent by ID. */\n async get(agentId: string): Promise<Agent> {\n return this.request(async () => {\n const res = await this.http.get<Agent>(`/agents/${agentId}`);\n return res.data;\n });\n }\n\n /** Create a new agent. */\n async create(agent: AgentCreate): Promise<Agent> {\n return this.request(async () => {\n const res = await this.http.post<Agent>('/agents/', agent);\n return res.data;\n });\n }\n\n /** Delete an agent by ID. */\n async delete(agentId: string): Promise<void> {\n return this.request(async () => {\n await this.http.delete(`/agents/${agentId}`);\n });\n }\n\n /** Execute an agent with input and optional conversation context. */\n async execute(agentId: string, input: string, messages: Array<{ role: string; content: string }> = [], conversationId?: string): Promise<AgentRun> {\n return this.request(async () => {\n const res = await this.http.post<AgentRun>(`/agents/${agentId}/execute`, {\n input,\n messages,\n conversation_id: conversationId,\n });\n return res.data;\n });\n }\n\n /** Fetch recent logs for an agent. */\n async logs(agentId: string, limit: number = 100): Promise<string[]> {\n return this.request(async () => {\n const res = await this.http.get<{ logs: string[] }>(`/agents/${agentId}/logs`, {\n params: { limit },\n });\n return res.data.logs;\n });\n }\n}\n","import { BaseClient, ClientConfig } from './base';\nimport FormData from 'form-data';\nimport fs from 'fs';\n\n// ── Types ──────────────────────────────────────────────────────────────────\n\nexport interface FileResponse {\n id: string;\n filename: string;\n purpose: string;\n bytes: number;\n created_at: string;\n}\n\n// ── Client ─────────────────────────────────────────────────────────────────\n\n/**\n * Client for managing file uploads (datasets for fine-tuning).\n *\n * @example\n * ```ts\n * const files = new FileClient({ apiKey: 'lt_...' });\n * const uploaded = await files.upload('./data.jsonl');\n * ```\n */\nexport class FileClient extends BaseClient {\n constructor(config: ClientConfig) {\n super(config);\n }\n\n /** Upload a file from a local path. */\n async upload(filePath: string, workspaceId?: string, purpose: string = 'fine-tune'): Promise<FileResponse> {\n if (!fs.existsSync(filePath)) {\n throw new Error(`File not found: ${filePath}`);\n }\n\n return this.request(async () => {\n const form = new FormData();\n form.append('file', fs.createReadStream(filePath));\n if (workspaceId) form.append('workspace_id', workspaceId);\n form.append('purpose', purpose);\n\n const res = await this.http.post<FileResponse>('/files', form, {\n headers: form.getHeaders(),\n maxContentLength: Infinity,\n maxBodyLength: Infinity,\n });\n return res.data;\n });\n }\n\n /** List files in a workspace, optionally filtered by purpose. */\n async list(workspaceId: string, purpose?: string): Promise<FileResponse[]> {\n return this.request(async () => {\n const params: Record<string, string> = { workspace_id: workspaceId };\n if (purpose) params.purpose = purpose;\n const res = await this.http.get<{ data: FileResponse[] }>('/files', { params });\n return res.data.data;\n });\n }\n\n /** Delete a file by ID. */\n async delete(fileId: string): Promise<void> {\n return this.request(async () => {\n await this.http.delete(`/files/${fileId}`);\n });\n }\n}\n","import { BaseClient, ClientConfig } from './base';\n\n// ── Types ──────────────────────────────────────────────────────────────────\n\nexport interface FineTuneHyperparameters {\n epochs?: number;\n learning_rate?: number;\n batch_size?: number;\n warmup_steps?: number;\n lora_rank?: number;\n lora_alpha?: number;\n weight_decay?: number;\n}\n\nexport interface FineTuneJobCreate {\n name?: string;\n base_model: string;\n model_id?: string;\n dataset_id: string;\n guardrail_id?: string;\n task?: 'text' | 'vision';\n training_method?: 'sft' | 'dpo' | 'rlhf' | 'lora' | 'qlora';\n hyperparameters?: FineTuneHyperparameters;\n}\n\nexport interface FineTuneJobResponse {\n id: string;\n name: string;\n status: 'pending' | 'running' | 'completed' | 'failed' | 'cancelled';\n progress: number;\n error_message?: string;\n base_model?: string;\n training_method?: string;\n created_at: string;\n started_at?: string;\n completed_at?: string;\n}\n\nexport interface FineTuneJobList {\n data: FineTuneJobResponse[];\n has_more: boolean;\n}\n\n// ── Client ─────────────────────────────────────────────────────────────────\n\n/**\n * Client for managing fine-tuning training jobs.\n *\n * @example\n * ```ts\n * const training = new TrainingClient({ apiKey: 'lt_...' });\n * const job = await training.createJob({\n * base_model: 'meta-llama/Llama-3.1-8B',\n * dataset_id: 'file_abc123',\n * training_method: 'lora',\n * });\n * ```\n */\nexport class TrainingClient extends BaseClient {\n constructor(config: ClientConfig) {\n super(config);\n }\n\n /** Create a new fine-tuning job. */\n async createJob(job: FineTuneJobCreate): Promise<FineTuneJobResponse> {\n return this.request(async () => {\n const res = await this.http.post<FineTuneJobResponse>('/finetune/jobs', job);\n return res.data;\n });\n }\n\n /** List fine-tuning jobs for a workspace. */\n async listJobs(workspaceId: string, limit: number = 10): Promise<FineTuneJobList> {\n return this.request(async () => {\n const res = await this.http.get<FineTuneJobList>('/finetune/jobs', {\n params: { workspace_id: workspaceId, limit },\n });\n return res.data;\n });\n }\n\n /** Get a specific job by ID. */\n async getJob(jobId: string): Promise<FineTuneJobResponse> {\n return this.request(async () => {\n const res = await this.http.get<FineTuneJobResponse>(`/finetune/jobs/${jobId}`);\n return res.data;\n });\n }\n\n /** Cancel a running job. */\n async cancelJob(jobId: string): Promise<FineTuneJobResponse> {\n return this.request(async () => {\n const res = await this.http.post<FineTuneJobResponse>(`/finetune/jobs/${jobId}/cancel`);\n return res.data;\n });\n }\n}\n","import { BaseClient, ClientConfig } from './base';\n\n// ── Types ──────────────────────────────────────────────────────────────────\n\nexport interface SubscriptionInfo {\n is_active: boolean;\n plan: string;\n plan_name: string;\n expires_at?: string;\n features: string[];\n limits: Record<string, number>;\n usage?: {\n tokensUsedThisMonth?: number;\n tokenLimit?: number;\n apiCalls?: number;\n };\n}\n\nexport interface FeatureCheck {\n feature: string;\n allowed: boolean;\n limit?: number;\n used?: number;\n}\n\n// ── Client ─────────────────────────────────────────────────────────────────\n\n/**\n * Client for checking subscription status and feature access.\n *\n * @example\n * ```ts\n * const sub = new SubscriptionClient({ apiKey: 'lt_...' });\n * const status = await sub.getStatus();\n * console.log(status.plan); // 'pro'\n * ```\n */\nexport class SubscriptionClient extends BaseClient {\n constructor(config: ClientConfig) {\n super(config);\n }\n\n /** Get current subscription status. */\n async getStatus(): Promise<SubscriptionInfo> {\n return this.request(async () => {\n const res = await this.http.get<SubscriptionInfo>('/subscription/status');\n return res.data;\n });\n }\n\n /** Check if a specific feature is available on the current plan. */\n async checkFeature(feature: string): Promise<FeatureCheck> {\n return this.request(async () => {\n const res = await this.http.get<FeatureCheck>(`/subscription/check/${feature}`);\n return res.data;\n });\n }\n\n /** Get usage analytics for the current subscription. */\n async getLimits(): Promise<Record<string, unknown>> {\n return this.request(async () => {\n const res = await this.http.get('/subscription/analytics');\n return res.data;\n });\n }\n}\n","import { BaseClient, ClientConfig } from './base';\n\n// ── Types ──────────────────────────────────────────────────────────────────\n\nexport interface Permission {\n id: string;\n object: string;\n created: number;\n allow_create_engine: boolean;\n allow_sampling: boolean;\n allow_logprobs: boolean;\n allow_search_indices: boolean;\n allow_view: boolean;\n allow_fine_tuning: boolean;\n organization: string;\n group: string | null;\n is_blocking: boolean;\n}\n\nexport interface Model {\n id: string;\n object: string;\n created: number;\n owned_by: string;\n permission: Permission[];\n root: string;\n parent: string | null;\n task?: 'text' | 'vision' | 'agent';\n}\n\n// ── Client ─────────────────────────────────────────────────────────────────\n\n/**\n * Client for browsing available base models.\n *\n * @example\n * ```ts\n * const models = new ModelClient({ apiKey: 'lt_...' });\n * const all = await models.list();\n * const textModels = await models.list('text');\n * ```\n */\nexport class ModelClient extends BaseClient {\n constructor(config: ClientConfig) {\n super(config);\n }\n\n /** List available models, optionally filtered by task type. */\n async list(task?: 'text' | 'vision' | 'agent'): Promise<Model[]> {\n return this.request(async () => {\n const params: Record<string, string> = {};\n if (task) params.task = task;\n const res = await this.http.get<{ data: Model[] }>('/models', { params });\n return res.data.data;\n });\n }\n\n /** Get a specific model by ID. */\n async get(modelId: string): Promise<Model> {\n return this.request(async () => {\n const res = await this.http.get<Model>(`/models/${modelId}`);\n return res.data;\n });\n }\n}\n","import { BaseClient, ClientConfig } from './base';\n\n// ── Types ──────────────────────────────────────────────────────────────────\n\nexport interface Secret {\n key: string;\n created_at: string;\n updated_at: string;\n}\n\n// ── Client ─────────────────────────────────────────────────────────────────\n\n/**\n * Client for managing workspace secrets and environment variables.\n *\n * @example\n * ```ts\n * const secrets = new SecretClient({ apiKey: 'lt_...' });\n * await secrets.set('OPENAI_KEY', 'sk-...');\n * const all = await secrets.list();\n * ```\n */\nexport class SecretClient extends BaseClient {\n constructor(config: ClientConfig) {\n super(config);\n }\n\n /** List all secrets in a workspace. Values are redacted. */\n async list(workspaceId?: string): Promise<Secret[]> {\n return this.request(async () => {\n const params: Record<string, string> = {};\n if (workspaceId) params.workspace_id = workspaceId;\n const res = await this.http.get<{ secrets: Secret[] }>('/secrets', { params });\n return res.data.secrets;\n });\n }\n\n /** Set (create or update) a secret. */\n async set(key: string, value: string, workspaceId?: string): Promise<Secret> {\n return this.request(async () => {\n const res = await this.http.post<Secret>('/secrets', { key, value, workspace_id: workspaceId });\n return res.data;\n });\n }\n\n /** Delete a secret by key. */\n async delete(key: string, workspaceId?: string): Promise<void> {\n return this.request(async () => {\n const params: Record<string, string> = {};\n if (workspaceId) params.workspace_id = workspaceId;\n await this.http.delete(`/secrets/${key}`, { params });\n });\n }\n}\n","import { BaseClient, ClientConfig } from './base';\n\n// ── Types ──────────────────────────────────────────────────────────────────\n\nexport interface GuardrailConfig {\n pii_enabled: boolean;\n pii_entities?: string[];\n profanity_enabled: boolean;\n profanity_threshold?: number;\n blocked_topics?: string[];\n regex_patterns?: string[];\n min_length?: number;\n max_length?: number;\n}\n\nexport interface Guardrail {\n id: string;\n workspace_id: string;\n name: string;\n description?: string;\n config: GuardrailConfig;\n is_active: boolean;\n created_at: string;\n updated_at: string;\n}\n\nexport interface GuardrailCreate {\n name: string;\n description?: string;\n config: GuardrailConfig;\n}\n\nexport interface GuardrailApplyResult {\n total_rows: number;\n passed: number;\n failed: number;\n violations: Array<{ row: number; rule: string; message: string }>;\n}\n\n// ── Client ─────────────────────────────────────────────────────────────────\n\n/**\n * Client for managing data guardrails (PII, profanity, length, regex).\n *\n * @example\n * ```ts\n * const guardrails = new GuardrailClient({ apiKey: 'lt_...' });\n * const rule = await guardrails.create({\n * name: 'PII Filter',\n * config: { pii_enabled: true, profanity_enabled: false },\n * });\n * ```\n */\nexport class GuardrailClient extends BaseClient {\n constructor(config: ClientConfig) {\n super(config);\n }\n\n /** List guardrails, optionally filtered by workspace. */\n async list(workspaceId?: string): Promise<Guardrail[]> {\n return this.request(async () => {\n const params: Record<string, string> = {};\n if (workspaceId) params.workspace_id = workspaceId;\n const res = await this.http.get<Guardrail[]>('/guardrails/', { params });\n return res.data;\n });\n }\n\n /** Get a guardrail by ID. */\n async get(guardrailId: string): Promise<Guardrail> {\n return this.request(async () => {\n const res = await this.http.get<Guardrail>(`/guardrails/${guardrailId}`);\n return res.data;\n });\n }\n\n /** Create a new guardrail. */\n async create(data: GuardrailCreate): Promise<Guardrail> {\n return this.request(async () => {\n const res = await this.http.post<Guardrail>('/guardrails/', data);\n return res.data;\n });\n }\n\n /** Delete a guardrail by ID. */\n async delete(guardrailId: string): Promise<void> {\n return this.request(async () => {\n await this.http.delete(`/guardrails/${guardrailId}`);\n });\n }\n\n /** Apply a guardrail to a dataset for validation. */\n async apply(datasetId: string, guardrailId: string): Promise<GuardrailApplyResult> {\n return this.request(async () => {\n const res = await this.http.post<GuardrailApplyResult>('/guardrails/apply', {\n dataset_id: datasetId,\n guardrail_id: guardrailId,\n });\n return res.data;\n });\n }\n}\n","import { BaseClient, ClientConfig } from './base';\n\n// ── Types ──────────────────────────────────────────────────────────────────\n\nexport interface UsageSummary {\n workspace_id: string;\n plan: string;\n quotas: Record<string, number>;\n billing?: {\n plan_id: string;\n tokens_used: number;\n tokens_limit: number;\n period_end: string;\n };\n}\n\nexport interface UsageHistoryPoint {\n date: string;\n tokens: number;\n agent_runs: number;\n cost: number;\n}\n\n// ── Client ─────────────────────────────────────────────────────────────────\n\n/**\n * Client for querying usage metrics and billing data.\n *\n * @example\n * ```ts\n * const usage = new UsageClient({ apiKey: 'lt_...' });\n * const summary = await usage.getSummary('ws_abc123');\n * console.log(summary.billing?.tokens_used);\n * ```\n */\nexport class UsageClient extends BaseClient {\n constructor(config: ClientConfig) {\n super(config);\n }\n\n /** Get current usage summary for a workspace. */\n async getSummary(workspaceId: string): Promise<UsageSummary> {\n return this.request(async () => {\n const res = await this.http.get<UsageSummary>('/usage', {\n params: { workspace_id: workspaceId },\n });\n return res.data;\n });\n }\n\n /** Get historical usage data for charts. */\n async getHistory(workspaceId: string, days: number = 30): Promise<UsageHistoryPoint[]> {\n return this.request(async () => {\n const res = await this.http.get<{ history: UsageHistoryPoint[] }>('/usage/history', {\n params: { workspace_id: workspaceId, days },\n });\n return res.data.history;\n });\n }\n}\n"]}