langtrain 0.1.25 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/chunk-36QS5AXY.mjs +3 -0
- package/dist/chunk-36QS5AXY.mjs.map +1 -0
- package/dist/chunk-ZN3AO753.js +3 -0
- package/dist/chunk-ZN3AO753.js.map +1 -0
- package/dist/cli.js +17 -9
- package/dist/cli.js.map +1 -1
- package/dist/cli.mjs +17 -9
- package/dist/cli.mjs.map +1 -1
- package/dist/index.d.mts +273 -84
- package/dist/index.d.ts +273 -84
- package/dist/index.js +1 -1
- package/dist/index.mjs +1 -1
- package/package.json +1 -1
- package/src/cli/auth.ts +63 -15
- package/src/cli/handlers/telemetry.ts +127 -0
- package/src/cli/index.ts +171 -144
- package/src/cli/menu.ts +36 -34
- package/src/index.ts +13 -9
- package/src/lib/agent.ts +71 -48
- package/src/lib/base.ts +152 -0
- package/src/lib/files.ts +52 -37
- package/src/lib/guardrails.ts +55 -25
- package/src/lib/models.ts +32 -28
- package/src/lib/secrets.ts +35 -20
- package/src/lib/subscription.ts +50 -30
- package/src/lib/training.ts +71 -38
- package/src/lib/usage.ts +60 -0
- package/dist/chunk-Q5EF25B2.js +0 -3
- package/dist/chunk-Q5EF25B2.js.map +0 -1
- package/dist/chunk-XRT7LLNF.mjs +0 -3
- package/dist/chunk-XRT7LLNF.mjs.map +0 -1
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { AxiosInstance } from 'axios';
|
|
1
2
|
import * as langvision from 'langvision';
|
|
2
3
|
export { langvision as Vision };
|
|
3
4
|
export { Langvision } from 'langvision';
|
|
@@ -5,17 +6,87 @@ import * as langtune from 'langtune';
|
|
|
5
6
|
export { langtune as Text };
|
|
6
7
|
export { Langtune } from 'langtune';
|
|
7
8
|
|
|
9
|
+
/** Configuration for all Langtrain SDK clients. */
|
|
10
|
+
interface ClientConfig {
|
|
11
|
+
/** Your Langtrain API key. */
|
|
12
|
+
apiKey: string;
|
|
13
|
+
/** Override the default API base URL. */
|
|
14
|
+
baseUrl?: string;
|
|
15
|
+
/** Request timeout in milliseconds (default: 30000). */
|
|
16
|
+
timeout?: number;
|
|
17
|
+
/** Maximum number of retries on transient errors (default: 2). */
|
|
18
|
+
maxRetries?: number;
|
|
19
|
+
}
|
|
20
|
+
declare class LangtrainError extends Error {
|
|
21
|
+
/** HTTP status code, if available. */
|
|
22
|
+
readonly status?: number;
|
|
23
|
+
/** Raw error code from the API. */
|
|
24
|
+
readonly code?: string;
|
|
25
|
+
/** The original error, if any. */
|
|
26
|
+
readonly cause?: Error;
|
|
27
|
+
constructor(message: string, options?: {
|
|
28
|
+
status?: number;
|
|
29
|
+
code?: string;
|
|
30
|
+
cause?: Error;
|
|
31
|
+
});
|
|
32
|
+
/** True if the error was a network/timeout issue (retryable). */
|
|
33
|
+
get isTransient(): boolean;
|
|
34
|
+
/** True if the API key was invalid or expired. */
|
|
35
|
+
get isAuthError(): boolean;
|
|
36
|
+
/** True if a resource was not found. */
|
|
37
|
+
get isNotFound(): boolean;
|
|
38
|
+
/** True if rate-limited. */
|
|
39
|
+
get isRateLimited(): boolean;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* BaseClient — abstract foundation for all Langtrain SDK clients.
|
|
43
|
+
*
|
|
44
|
+
* Provides:
|
|
45
|
+
* - Shared axios instance with API key auth
|
|
46
|
+
* - Configurable timeouts
|
|
47
|
+
* - Automatic retry with exponential backoff on transient errors
|
|
48
|
+
* - Structured error wrapping (LangtrainError)
|
|
49
|
+
*/
|
|
50
|
+
declare abstract class BaseClient {
|
|
51
|
+
protected readonly http: AxiosInstance;
|
|
52
|
+
protected readonly maxRetries: number;
|
|
53
|
+
constructor(config: ClientConfig);
|
|
54
|
+
/**
|
|
55
|
+
* Execute a request with automatic retry and error wrapping.
|
|
56
|
+
*/
|
|
57
|
+
protected request<T>(fn: () => Promise<T>): Promise<T>;
|
|
58
|
+
/**
|
|
59
|
+
* Wrap any thrown error into a structured LangtrainError.
|
|
60
|
+
*/
|
|
61
|
+
private wrapError;
|
|
62
|
+
private sleep;
|
|
63
|
+
}
|
|
64
|
+
|
|
8
65
|
interface Agent {
|
|
9
66
|
id: string;
|
|
10
67
|
workspace_id: string;
|
|
11
68
|
name: string;
|
|
12
69
|
description?: string;
|
|
13
70
|
model_id?: string;
|
|
14
|
-
config:
|
|
71
|
+
config: AgentConfig;
|
|
15
72
|
is_active: boolean;
|
|
16
73
|
created_at: string;
|
|
17
74
|
updated_at: string;
|
|
18
75
|
}
|
|
76
|
+
interface AgentConfig {
|
|
77
|
+
system_prompt?: string;
|
|
78
|
+
temperature?: number;
|
|
79
|
+
max_tokens?: number;
|
|
80
|
+
tools?: string[];
|
|
81
|
+
[key: string]: unknown;
|
|
82
|
+
}
|
|
83
|
+
interface AgentCreate {
|
|
84
|
+
workspace_id: string;
|
|
85
|
+
name: string;
|
|
86
|
+
description?: string;
|
|
87
|
+
model_id?: string;
|
|
88
|
+
config?: AgentConfig;
|
|
89
|
+
}
|
|
19
90
|
interface AgentRun {
|
|
20
91
|
id: string;
|
|
21
92
|
conversation_id: string;
|
|
@@ -25,35 +96,33 @@ interface AgentRun {
|
|
|
25
96
|
latency_ms: number;
|
|
26
97
|
tokens_used: number;
|
|
27
98
|
}
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
99
|
+
/**
|
|
100
|
+
* Client for managing AI agents — create, execute, and monitor.
|
|
101
|
+
*
|
|
102
|
+
* @example
|
|
103
|
+
* ```ts
|
|
104
|
+
* const agents = new AgentClient({ apiKey: 'lt_...' });
|
|
105
|
+
* const list = await agents.list();
|
|
106
|
+
* const result = await agents.execute(list[0].id, 'Hello!');
|
|
107
|
+
* ```
|
|
108
|
+
*/
|
|
109
|
+
declare class AgentClient extends BaseClient {
|
|
110
|
+
constructor(config: ClientConfig);
|
|
111
|
+
/** List all agents, optionally filtered by workspace. */
|
|
35
112
|
list(workspaceId?: string): Promise<Agent[]>;
|
|
113
|
+
/** Get a single agent by ID. */
|
|
36
114
|
get(agentId: string): Promise<Agent>;
|
|
115
|
+
/** Create a new agent. */
|
|
37
116
|
create(agent: AgentCreate): Promise<Agent>;
|
|
117
|
+
/** Delete an agent by ID. */
|
|
38
118
|
delete(agentId: string): Promise<void>;
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
temperature?: number;
|
|
47
|
-
max_tokens?: number;
|
|
48
|
-
tools?: string[];
|
|
49
|
-
[key: string]: any;
|
|
50
|
-
}
|
|
51
|
-
interface AgentCreate {
|
|
52
|
-
workspace_id: string;
|
|
53
|
-
name: string;
|
|
54
|
-
description?: string;
|
|
55
|
-
model_id?: string;
|
|
56
|
-
config?: AgentConfig;
|
|
119
|
+
/** Execute an agent with input and optional conversation context. */
|
|
120
|
+
execute(agentId: string, input: string, messages?: Array<{
|
|
121
|
+
role: string;
|
|
122
|
+
content: string;
|
|
123
|
+
}>, conversationId?: string): Promise<AgentRun>;
|
|
124
|
+
/** Fetch recent logs for an agent. */
|
|
125
|
+
logs(agentId: string, limit?: number): Promise<string[]>;
|
|
57
126
|
}
|
|
58
127
|
|
|
59
128
|
type agent_Agent = Agent;
|
|
@@ -66,15 +135,6 @@ declare namespace agent {
|
|
|
66
135
|
export { type agent_Agent as Agent, agent_AgentClient as AgentClient, type agent_AgentConfig as AgentConfig, type agent_AgentCreate as AgentCreate, type agent_AgentRun as AgentRun };
|
|
67
136
|
}
|
|
68
137
|
|
|
69
|
-
declare class FileClient {
|
|
70
|
-
private client;
|
|
71
|
-
constructor(config: {
|
|
72
|
-
apiKey: string;
|
|
73
|
-
baseUrl?: string;
|
|
74
|
-
});
|
|
75
|
-
upload(file: any, workspaceId?: string, purpose?: string): Promise<FileResponse>;
|
|
76
|
-
list(workspaceId: string, purpose?: string): Promise<FileResponse[]>;
|
|
77
|
-
}
|
|
78
138
|
interface FileResponse {
|
|
79
139
|
id: string;
|
|
80
140
|
filename: string;
|
|
@@ -82,17 +142,33 @@ interface FileResponse {
|
|
|
82
142
|
bytes: number;
|
|
83
143
|
created_at: string;
|
|
84
144
|
}
|
|
145
|
+
/**
|
|
146
|
+
* Client for managing file uploads (datasets for fine-tuning).
|
|
147
|
+
*
|
|
148
|
+
* @example
|
|
149
|
+
* ```ts
|
|
150
|
+
* const files = new FileClient({ apiKey: 'lt_...' });
|
|
151
|
+
* const uploaded = await files.upload('./data.jsonl');
|
|
152
|
+
* ```
|
|
153
|
+
*/
|
|
154
|
+
declare class FileClient extends BaseClient {
|
|
155
|
+
constructor(config: ClientConfig);
|
|
156
|
+
/** Upload a file from a local path. */
|
|
157
|
+
upload(filePath: string, workspaceId?: string, purpose?: string): Promise<FileResponse>;
|
|
158
|
+
/** List files in a workspace, optionally filtered by purpose. */
|
|
159
|
+
list(workspaceId: string, purpose?: string): Promise<FileResponse[]>;
|
|
160
|
+
/** Delete a file by ID. */
|
|
161
|
+
delete(fileId: string): Promise<void>;
|
|
162
|
+
}
|
|
85
163
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
getJob(jobId: string): Promise<FineTuneJobResponse>;
|
|
95
|
-
cancelJob(jobId: string): Promise<FineTuneJobResponse>;
|
|
164
|
+
interface FineTuneHyperparameters {
|
|
165
|
+
epochs?: number;
|
|
166
|
+
learning_rate?: number;
|
|
167
|
+
batch_size?: number;
|
|
168
|
+
warmup_steps?: number;
|
|
169
|
+
lora_rank?: number;
|
|
170
|
+
lora_alpha?: number;
|
|
171
|
+
weight_decay?: number;
|
|
96
172
|
}
|
|
97
173
|
interface FineTuneJobCreate {
|
|
98
174
|
name?: string;
|
|
@@ -102,40 +178,61 @@ interface FineTuneJobCreate {
|
|
|
102
178
|
guardrail_id?: string;
|
|
103
179
|
task?: 'text' | 'vision';
|
|
104
180
|
training_method?: 'sft' | 'dpo' | 'rlhf' | 'lora' | 'qlora';
|
|
105
|
-
hyperparameters?:
|
|
106
|
-
[key: string]: any;
|
|
181
|
+
hyperparameters?: FineTuneHyperparameters;
|
|
107
182
|
}
|
|
108
183
|
interface FineTuneJobResponse {
|
|
109
184
|
id: string;
|
|
110
185
|
name: string;
|
|
111
|
-
status:
|
|
186
|
+
status: 'pending' | 'running' | 'completed' | 'failed' | 'cancelled';
|
|
112
187
|
progress: number;
|
|
113
188
|
error_message?: string;
|
|
189
|
+
base_model?: string;
|
|
190
|
+
training_method?: string;
|
|
114
191
|
created_at: string;
|
|
115
|
-
|
|
192
|
+
started_at?: string;
|
|
193
|
+
completed_at?: string;
|
|
116
194
|
}
|
|
117
195
|
interface FineTuneJobList {
|
|
118
196
|
data: FineTuneJobResponse[];
|
|
119
197
|
has_more: boolean;
|
|
120
198
|
}
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
199
|
+
/**
|
|
200
|
+
* Client for managing fine-tuning training jobs.
|
|
201
|
+
*
|
|
202
|
+
* @example
|
|
203
|
+
* ```ts
|
|
204
|
+
* const training = new TrainingClient({ apiKey: 'lt_...' });
|
|
205
|
+
* const job = await training.createJob({
|
|
206
|
+
* base_model: 'meta-llama/Llama-3.1-8B',
|
|
207
|
+
* dataset_id: 'file_abc123',
|
|
208
|
+
* training_method: 'lora',
|
|
209
|
+
* });
|
|
210
|
+
* ```
|
|
211
|
+
*/
|
|
212
|
+
declare class TrainingClient extends BaseClient {
|
|
213
|
+
constructor(config: ClientConfig);
|
|
214
|
+
/** Create a new fine-tuning job. */
|
|
215
|
+
createJob(job: FineTuneJobCreate): Promise<FineTuneJobResponse>;
|
|
216
|
+
/** List fine-tuning jobs for a workspace. */
|
|
217
|
+
listJobs(workspaceId: string, limit?: number): Promise<FineTuneJobList>;
|
|
218
|
+
/** Get a specific job by ID. */
|
|
219
|
+
getJob(jobId: string): Promise<FineTuneJobResponse>;
|
|
220
|
+
/** Cancel a running job. */
|
|
221
|
+
cancelJob(jobId: string): Promise<FineTuneJobResponse>;
|
|
131
222
|
}
|
|
223
|
+
|
|
132
224
|
interface SubscriptionInfo {
|
|
133
225
|
is_active: boolean;
|
|
134
226
|
plan: string;
|
|
135
227
|
plan_name: string;
|
|
136
228
|
expires_at?: string;
|
|
137
229
|
features: string[];
|
|
138
|
-
limits:
|
|
230
|
+
limits: Record<string, number>;
|
|
231
|
+
usage?: {
|
|
232
|
+
tokensUsedThisMonth?: number;
|
|
233
|
+
tokenLimit?: number;
|
|
234
|
+
apiCalls?: number;
|
|
235
|
+
};
|
|
139
236
|
}
|
|
140
237
|
interface FeatureCheck {
|
|
141
238
|
feature: string;
|
|
@@ -143,6 +240,25 @@ interface FeatureCheck {
|
|
|
143
240
|
limit?: number;
|
|
144
241
|
used?: number;
|
|
145
242
|
}
|
|
243
|
+
/**
|
|
244
|
+
* Client for checking subscription status and feature access.
|
|
245
|
+
*
|
|
246
|
+
* @example
|
|
247
|
+
* ```ts
|
|
248
|
+
* const sub = new SubscriptionClient({ apiKey: 'lt_...' });
|
|
249
|
+
* const status = await sub.getStatus();
|
|
250
|
+
* console.log(status.plan); // 'pro'
|
|
251
|
+
* ```
|
|
252
|
+
*/
|
|
253
|
+
declare class SubscriptionClient extends BaseClient {
|
|
254
|
+
constructor(config: ClientConfig);
|
|
255
|
+
/** Get current subscription status. */
|
|
256
|
+
getStatus(): Promise<SubscriptionInfo>;
|
|
257
|
+
/** Check if a specific feature is available on the current plan. */
|
|
258
|
+
checkFeature(feature: string): Promise<FeatureCheck>;
|
|
259
|
+
/** Get usage analytics for the current subscription. */
|
|
260
|
+
getLimits(): Promise<Record<string, unknown>>;
|
|
261
|
+
}
|
|
146
262
|
|
|
147
263
|
interface Permission {
|
|
148
264
|
id: string;
|
|
@@ -155,7 +271,7 @@ interface Permission {
|
|
|
155
271
|
allow_view: boolean;
|
|
156
272
|
allow_fine_tuning: boolean;
|
|
157
273
|
organization: string;
|
|
158
|
-
group:
|
|
274
|
+
group: string | null;
|
|
159
275
|
is_blocking: boolean;
|
|
160
276
|
}
|
|
161
277
|
interface Model {
|
|
@@ -168,13 +284,21 @@ interface Model {
|
|
|
168
284
|
parent: string | null;
|
|
169
285
|
task?: 'text' | 'vision' | 'agent';
|
|
170
286
|
}
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
287
|
+
/**
|
|
288
|
+
* Client for browsing available base models.
|
|
289
|
+
*
|
|
290
|
+
* @example
|
|
291
|
+
* ```ts
|
|
292
|
+
* const models = new ModelClient({ apiKey: 'lt_...' });
|
|
293
|
+
* const all = await models.list();
|
|
294
|
+
* const textModels = await models.list('text');
|
|
295
|
+
* ```
|
|
296
|
+
*/
|
|
297
|
+
declare class ModelClient extends BaseClient {
|
|
298
|
+
constructor(config: ClientConfig);
|
|
299
|
+
/** List available models, optionally filtered by task type. */
|
|
300
|
+
list(task?: 'text' | 'vision' | 'agent'): Promise<Model[]>;
|
|
301
|
+
/** Get a specific model by ID. */
|
|
178
302
|
get(modelId: string): Promise<Model>;
|
|
179
303
|
}
|
|
180
304
|
|
|
@@ -191,15 +315,23 @@ interface Secret {
|
|
|
191
315
|
created_at: string;
|
|
192
316
|
updated_at: string;
|
|
193
317
|
}
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
318
|
+
/**
|
|
319
|
+
* Client for managing workspace secrets and environment variables.
|
|
320
|
+
*
|
|
321
|
+
* @example
|
|
322
|
+
* ```ts
|
|
323
|
+
* const secrets = new SecretClient({ apiKey: 'lt_...' });
|
|
324
|
+
* await secrets.set('OPENAI_KEY', 'sk-...');
|
|
325
|
+
* const all = await secrets.list();
|
|
326
|
+
* ```
|
|
327
|
+
*/
|
|
328
|
+
declare class SecretClient extends BaseClient {
|
|
329
|
+
constructor(config: ClientConfig);
|
|
330
|
+
/** List all secrets in a workspace. Values are redacted. */
|
|
201
331
|
list(workspaceId?: string): Promise<Secret[]>;
|
|
332
|
+
/** Set (create or update) a secret. */
|
|
202
333
|
set(key: string, value: string, workspaceId?: string): Promise<Secret>;
|
|
334
|
+
/** Delete a secret by key. */
|
|
203
335
|
delete(key: string, workspaceId?: string): Promise<void>;
|
|
204
336
|
}
|
|
205
337
|
|
|
@@ -235,18 +367,75 @@ interface GuardrailCreate {
|
|
|
235
367
|
description?: string;
|
|
236
368
|
config: GuardrailConfig;
|
|
237
369
|
}
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
370
|
+
interface GuardrailApplyResult {
|
|
371
|
+
total_rows: number;
|
|
372
|
+
passed: number;
|
|
373
|
+
failed: number;
|
|
374
|
+
violations: Array<{
|
|
375
|
+
row: number;
|
|
376
|
+
rule: string;
|
|
377
|
+
message: string;
|
|
378
|
+
}>;
|
|
379
|
+
}
|
|
380
|
+
/**
|
|
381
|
+
* Client for managing data guardrails (PII, profanity, length, regex).
|
|
382
|
+
*
|
|
383
|
+
* @example
|
|
384
|
+
* ```ts
|
|
385
|
+
* const guardrails = new GuardrailClient({ apiKey: 'lt_...' });
|
|
386
|
+
* const rule = await guardrails.create({
|
|
387
|
+
* name: 'PII Filter',
|
|
388
|
+
* config: { pii_enabled: true, profanity_enabled: false },
|
|
389
|
+
* });
|
|
390
|
+
* ```
|
|
391
|
+
*/
|
|
392
|
+
declare class GuardrailClient extends BaseClient {
|
|
393
|
+
constructor(config: ClientConfig);
|
|
394
|
+
/** List guardrails, optionally filtered by workspace. */
|
|
245
395
|
list(workspaceId?: string): Promise<Guardrail[]>;
|
|
396
|
+
/** Get a guardrail by ID. */
|
|
246
397
|
get(guardrailId: string): Promise<Guardrail>;
|
|
398
|
+
/** Create a new guardrail. */
|
|
247
399
|
create(data: GuardrailCreate): Promise<Guardrail>;
|
|
400
|
+
/** Delete a guardrail by ID. */
|
|
248
401
|
delete(guardrailId: string): Promise<void>;
|
|
249
|
-
|
|
402
|
+
/** Apply a guardrail to a dataset for validation. */
|
|
403
|
+
apply(datasetId: string, guardrailId: string): Promise<GuardrailApplyResult>;
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
interface UsageSummary {
|
|
407
|
+
workspace_id: string;
|
|
408
|
+
plan: string;
|
|
409
|
+
quotas: Record<string, number>;
|
|
410
|
+
billing?: {
|
|
411
|
+
plan_id: string;
|
|
412
|
+
tokens_used: number;
|
|
413
|
+
tokens_limit: number;
|
|
414
|
+
period_end: string;
|
|
415
|
+
};
|
|
416
|
+
}
|
|
417
|
+
interface UsageHistoryPoint {
|
|
418
|
+
date: string;
|
|
419
|
+
tokens: number;
|
|
420
|
+
agent_runs: number;
|
|
421
|
+
cost: number;
|
|
422
|
+
}
|
|
423
|
+
/**
|
|
424
|
+
* Client for querying usage metrics and billing data.
|
|
425
|
+
*
|
|
426
|
+
* @example
|
|
427
|
+
* ```ts
|
|
428
|
+
* const usage = new UsageClient({ apiKey: 'lt_...' });
|
|
429
|
+
* const summary = await usage.getSummary('ws_abc123');
|
|
430
|
+
* console.log(summary.billing?.tokens_used);
|
|
431
|
+
* ```
|
|
432
|
+
*/
|
|
433
|
+
declare class UsageClient extends BaseClient {
|
|
434
|
+
constructor(config: ClientConfig);
|
|
435
|
+
/** Get current usage summary for a workspace. */
|
|
436
|
+
getSummary(workspaceId: string): Promise<UsageSummary>;
|
|
437
|
+
/** Get historical usage data for charts. */
|
|
438
|
+
getHistory(workspaceId: string, days?: number): Promise<UsageHistoryPoint[]>;
|
|
250
439
|
}
|
|
251
440
|
|
|
252
|
-
export { type Agent, AgentClient, type AgentCreate, type AgentRun, agent as AgentTypes, type FeatureCheck, FileClient, type FileResponse, type FineTuneJobCreate, type FineTuneJobResponse, type Guardrail, GuardrailClient, type GuardrailConfig, type GuardrailCreate, type Model, ModelClient, models as ModelTypes, type Secret, SecretClient, secrets as SecretTypes, SubscriptionClient, type SubscriptionInfo, TrainingClient };
|
|
441
|
+
export { type Agent, AgentClient, type AgentConfig, type AgentCreate, type AgentRun, agent as AgentTypes, BaseClient, type ClientConfig, type FeatureCheck, FileClient, type FileResponse, type FineTuneHyperparameters, type FineTuneJobCreate, type FineTuneJobList, type FineTuneJobResponse, type Guardrail, type GuardrailApplyResult, GuardrailClient, type GuardrailConfig, type GuardrailCreate, LangtrainError, type Model, ModelClient, models as ModelTypes, type Permission, type Secret, SecretClient, secrets as SecretTypes, SubscriptionClient, type SubscriptionInfo, TrainingClient, UsageClient, type UsageHistoryPoint, type UsageSummary };
|
package/dist/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
'use strict';var
|
|
1
|
+
'use strict';var chunkZN3AO753_js=require('./chunk-ZN3AO753.js');Object.defineProperty(exports,"AgentClient",{enumerable:true,get:function(){return chunkZN3AO753_js.d}});Object.defineProperty(exports,"AgentTypes",{enumerable:true,get:function(){return chunkZN3AO753_js.e}});Object.defineProperty(exports,"BaseClient",{enumerable:true,get:function(){return chunkZN3AO753_js.c}});Object.defineProperty(exports,"FileClient",{enumerable:true,get:function(){return chunkZN3AO753_js.f}});Object.defineProperty(exports,"GuardrailClient",{enumerable:true,get:function(){return chunkZN3AO753_js.m}});Object.defineProperty(exports,"LangtrainError",{enumerable:true,get:function(){return chunkZN3AO753_js.b}});Object.defineProperty(exports,"Langtune",{enumerable:true,get:function(){return chunkZN3AO753_js.r}});Object.defineProperty(exports,"Langvision",{enumerable:true,get:function(){return chunkZN3AO753_js.q}});Object.defineProperty(exports,"ModelClient",{enumerable:true,get:function(){return chunkZN3AO753_js.i}});Object.defineProperty(exports,"ModelTypes",{enumerable:true,get:function(){return chunkZN3AO753_js.j}});Object.defineProperty(exports,"SecretClient",{enumerable:true,get:function(){return chunkZN3AO753_js.k}});Object.defineProperty(exports,"SecretTypes",{enumerable:true,get:function(){return chunkZN3AO753_js.l}});Object.defineProperty(exports,"SubscriptionClient",{enumerable:true,get:function(){return chunkZN3AO753_js.h}});Object.defineProperty(exports,"Text",{enumerable:true,get:function(){return chunkZN3AO753_js.p}});Object.defineProperty(exports,"TrainingClient",{enumerable:true,get:function(){return chunkZN3AO753_js.g}});Object.defineProperty(exports,"UsageClient",{enumerable:true,get:function(){return chunkZN3AO753_js.n}});Object.defineProperty(exports,"Vision",{enumerable:true,get:function(){return chunkZN3AO753_js.o}});//# sourceMappingURL=index.js.map
|
|
2
2
|
//# sourceMappingURL=index.js.map
|
package/dist/index.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
|
|
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-36QS5AXY.mjs';//# sourceMappingURL=index.mjs.map
|
|
2
2
|
//# sourceMappingURL=index.mjs.map
|
package/package.json
CHANGED
package/src/cli/auth.ts
CHANGED
|
@@ -1,12 +1,25 @@
|
|
|
1
|
-
import { password, isCancel, cancel, intro, green, yellow, red, bgMagenta, black, spinner, gray } from './ui';
|
|
1
|
+
import { password, isCancel, cancel, intro, green, yellow, red, bgMagenta, black, spinner, gray, cyan, dim, bold } from './ui';
|
|
2
2
|
import { getConfig, saveConfig } from './config';
|
|
3
3
|
import { SubscriptionClient, SubscriptionInfo } from '../index';
|
|
4
4
|
|
|
5
|
+
/**
|
|
6
|
+
* Quick check if API key is stored (no network call).
|
|
7
|
+
*/
|
|
8
|
+
export function isAuthenticated(): boolean {
|
|
9
|
+
const config = getConfig();
|
|
10
|
+
return !!config.apiKey;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Ensure auth — if not logged in, forces login flow.
|
|
15
|
+
*/
|
|
5
16
|
export async function ensureAuth(): Promise<string> {
|
|
6
17
|
let config = getConfig();
|
|
7
18
|
|
|
8
19
|
if (!config.apiKey) {
|
|
9
|
-
|
|
20
|
+
console.log('');
|
|
21
|
+
console.log(yellow(' Authentication required.'));
|
|
22
|
+
console.log(gray(' Login to access all features.\n'));
|
|
10
23
|
await handleLogin();
|
|
11
24
|
config = getConfig();
|
|
12
25
|
}
|
|
@@ -14,13 +27,20 @@ export async function ensureAuth(): Promise<string> {
|
|
|
14
27
|
return config.apiKey as string;
|
|
15
28
|
}
|
|
16
29
|
|
|
30
|
+
/**
|
|
31
|
+
* Interactive login — Claude-style API key entry with immediate verification.
|
|
32
|
+
*/
|
|
17
33
|
export async function handleLogin() {
|
|
18
34
|
while (true) {
|
|
19
|
-
console.log(
|
|
35
|
+
console.log(dim(' ─────────────────────────────────────'));
|
|
36
|
+
console.log(gray(' Get your API Key at: ') + cyan('https://app.langtrain.xyz/home/api'));
|
|
37
|
+
console.log(dim(' ─────────────────────────────────────\n'));
|
|
38
|
+
|
|
20
39
|
const apiKey = await password({
|
|
21
40
|
message: 'Enter your Langtrain API Key:',
|
|
22
41
|
validate(value) {
|
|
23
42
|
if (!value || value.length === 0) return 'API Key is required';
|
|
43
|
+
if (value.length < 10) return 'Invalid key format';
|
|
24
44
|
},
|
|
25
45
|
});
|
|
26
46
|
|
|
@@ -32,45 +52,73 @@ export async function handleLogin() {
|
|
|
32
52
|
const s = spinner();
|
|
33
53
|
s.start('Verifying API Key...');
|
|
34
54
|
|
|
35
|
-
// Verify key immediately
|
|
36
55
|
try {
|
|
37
56
|
const client = new SubscriptionClient({ apiKey: apiKey as string });
|
|
38
57
|
const info = await client.getStatus();
|
|
39
58
|
|
|
40
|
-
|
|
59
|
+
const planBadge = info.plan === 'pro'
|
|
60
|
+
? bgMagenta(black(' PRO '))
|
|
61
|
+
: info.plan === 'enterprise'
|
|
62
|
+
? bgMagenta(black(' ENTERPRISE '))
|
|
63
|
+
: ' FREE ';
|
|
64
|
+
|
|
65
|
+
s.stop(green(`Authenticated ${planBadge}`));
|
|
66
|
+
|
|
67
|
+
// Show initial token info if available
|
|
68
|
+
if (info.usage) {
|
|
69
|
+
const used = info.usage.tokensUsedThisMonth || 0;
|
|
70
|
+
const limit = info.usage.tokenLimit || 10000;
|
|
71
|
+
const pct = Math.round((used / limit) * 100);
|
|
72
|
+
console.log(dim(` Tokens: ${used.toLocaleString()} / ${limit.toLocaleString()} (${pct}% used)`));
|
|
73
|
+
}
|
|
41
74
|
|
|
42
75
|
const config = getConfig();
|
|
43
76
|
saveConfig({ ...config, apiKey: apiKey as string });
|
|
44
|
-
|
|
45
|
-
return;
|
|
77
|
+
console.log(green(' ✔ Credentials saved to ~/.langtrain/config.json\n'));
|
|
78
|
+
return;
|
|
46
79
|
} catch (e: any) {
|
|
47
80
|
s.stop(red('Invalid API Key. Please try again.'));
|
|
48
|
-
// Loop continues
|
|
49
81
|
}
|
|
50
82
|
}
|
|
51
83
|
}
|
|
52
84
|
|
|
85
|
+
/**
|
|
86
|
+
* Logout — clear stored credentials.
|
|
87
|
+
*/
|
|
88
|
+
export async function handleLogout() {
|
|
89
|
+
const config = getConfig();
|
|
90
|
+
delete config.apiKey;
|
|
91
|
+
saveConfig(config);
|
|
92
|
+
console.log(green('\n ✔ Logged out. Credentials cleared.\n'));
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Fetch subscription info for status bar display.
|
|
97
|
+
*/
|
|
53
98
|
export async function getSubscription(apiKey: string): Promise<SubscriptionInfo | null> {
|
|
54
99
|
const client = new SubscriptionClient({ apiKey });
|
|
55
100
|
const s = spinner();
|
|
56
|
-
s.start('
|
|
101
|
+
s.start('Checking subscription...');
|
|
57
102
|
try {
|
|
58
103
|
const info = await client.getStatus();
|
|
59
104
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
105
|
+
const planBadge = info.plan === 'pro'
|
|
106
|
+
? bgMagenta(black(' PRO '))
|
|
107
|
+
: info.plan === 'enterprise'
|
|
108
|
+
? bgMagenta(black(' ENTERPRISE '))
|
|
109
|
+
: bold(' FREE ');
|
|
110
|
+
|
|
111
|
+
s.stop(green(`Plan: ${planBadge}`));
|
|
63
112
|
|
|
64
113
|
if (info.is_active === false) {
|
|
65
|
-
console.log(yellow('
|
|
114
|
+
console.log(yellow(' ⚠ Subscription inactive. Some features may be limited.\n'));
|
|
66
115
|
}
|
|
67
116
|
|
|
68
117
|
return info;
|
|
69
118
|
} catch (e: any) {
|
|
70
119
|
s.stop(red('Failed to verify subscription.'));
|
|
71
120
|
if (e.response && e.response.status === 401) {
|
|
72
|
-
console.log(red('
|
|
73
|
-
// Optionally clear key?
|
|
121
|
+
console.log(red(' API Key expired. Please login again.'));
|
|
74
122
|
}
|
|
75
123
|
return null;
|
|
76
124
|
}
|