langtrain 0.1.26 → 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 +10 -10
- package/dist/cli.js.map +1 -1
- package/dist/cli.mjs +9 -9
- package/dist/cli.mjs.map +1 -1
- package/dist/index.d.mts +248 -98
- package/dist/index.d.ts +248 -98
- package/dist/index.js +1 -1
- package/dist/index.mjs +1 -1
- package/package.json +1 -1
- package/src/index.ts +12 -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 +45 -30
- package/src/lib/training.ts +71 -38
- package/src/lib/usage.ts +29 -24
- package/dist/chunk-7D4BGTDT.js +0 -3
- package/dist/chunk-7D4BGTDT.js.map +0 -1
- package/dist/chunk-O3AFVWU4.mjs +0 -3
- package/dist/chunk-O3AFVWU4.mjs.map +0 -1
package/src/lib/agent.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { BaseClient, ClientConfig } from './base';
|
|
2
|
+
|
|
3
|
+
// ── Types ──────────────────────────────────────────────────────────────────
|
|
2
4
|
|
|
3
5
|
export interface Agent {
|
|
4
6
|
id: string;
|
|
@@ -6,12 +8,28 @@ export interface Agent {
|
|
|
6
8
|
name: string;
|
|
7
9
|
description?: string;
|
|
8
10
|
model_id?: string;
|
|
9
|
-
config:
|
|
11
|
+
config: AgentConfig;
|
|
10
12
|
is_active: boolean;
|
|
11
13
|
created_at: string;
|
|
12
14
|
updated_at: string;
|
|
13
15
|
}
|
|
14
16
|
|
|
17
|
+
export interface AgentConfig {
|
|
18
|
+
system_prompt?: string;
|
|
19
|
+
temperature?: number;
|
|
20
|
+
max_tokens?: number;
|
|
21
|
+
tools?: string[];
|
|
22
|
+
[key: string]: unknown;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export interface AgentCreate {
|
|
26
|
+
workspace_id: string;
|
|
27
|
+
name: string;
|
|
28
|
+
description?: string;
|
|
29
|
+
model_id?: string;
|
|
30
|
+
config?: AgentConfig;
|
|
31
|
+
}
|
|
32
|
+
|
|
15
33
|
export interface AgentRun {
|
|
16
34
|
id: string;
|
|
17
35
|
conversation_id: string;
|
|
@@ -22,70 +40,75 @@ export interface AgentRun {
|
|
|
22
40
|
tokens_used: number;
|
|
23
41
|
}
|
|
24
42
|
|
|
25
|
-
|
|
26
|
-
private client: AxiosInstance;
|
|
43
|
+
// ── Client ─────────────────────────────────────────────────────────────────
|
|
27
44
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
45
|
+
/**
|
|
46
|
+
* Client for managing AI agents — create, execute, and monitor.
|
|
47
|
+
*
|
|
48
|
+
* @example
|
|
49
|
+
* ```ts
|
|
50
|
+
* const agents = new AgentClient({ apiKey: 'lt_...' });
|
|
51
|
+
* const list = await agents.list();
|
|
52
|
+
* const result = await agents.execute(list[0].id, 'Hello!');
|
|
53
|
+
* ```
|
|
54
|
+
*/
|
|
55
|
+
export class AgentClient extends BaseClient {
|
|
56
|
+
constructor(config: ClientConfig) {
|
|
57
|
+
super(config);
|
|
36
58
|
}
|
|
37
59
|
|
|
60
|
+
/** List all agents, optionally filtered by workspace. */
|
|
38
61
|
async list(workspaceId?: string): Promise<Agent[]> {
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
62
|
+
return this.request(async () => {
|
|
63
|
+
const params: Record<string, string> = {};
|
|
64
|
+
if (workspaceId) params.workspace_id = workspaceId;
|
|
65
|
+
const res = await this.http.get<{ agents: Agent[] }>('/agents', { params });
|
|
66
|
+
return res.data.agents;
|
|
67
|
+
});
|
|
44
68
|
}
|
|
45
69
|
|
|
70
|
+
/** Get a single agent by ID. */
|
|
46
71
|
async get(agentId: string): Promise<Agent> {
|
|
47
|
-
|
|
48
|
-
|
|
72
|
+
return this.request(async () => {
|
|
73
|
+
const res = await this.http.get<Agent>(`/agents/${agentId}`);
|
|
74
|
+
return res.data;
|
|
75
|
+
});
|
|
49
76
|
}
|
|
50
77
|
|
|
78
|
+
/** Create a new agent. */
|
|
51
79
|
async create(agent: AgentCreate): Promise<Agent> {
|
|
52
|
-
|
|
53
|
-
|
|
80
|
+
return this.request(async () => {
|
|
81
|
+
const res = await this.http.post<Agent>('/agents/', agent);
|
|
82
|
+
return res.data;
|
|
83
|
+
});
|
|
54
84
|
}
|
|
55
85
|
|
|
86
|
+
/** Delete an agent by ID. */
|
|
56
87
|
async delete(agentId: string): Promise<void> {
|
|
57
|
-
|
|
88
|
+
return this.request(async () => {
|
|
89
|
+
await this.http.delete(`/agents/${agentId}`);
|
|
90
|
+
});
|
|
58
91
|
}
|
|
59
92
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
93
|
+
/** Execute an agent with input and optional conversation context. */
|
|
94
|
+
async execute(agentId: string, input: string, messages: Array<{ role: string; content: string }> = [], conversationId?: string): Promise<AgentRun> {
|
|
95
|
+
return this.request(async () => {
|
|
96
|
+
const res = await this.http.post<AgentRun>(`/agents/${agentId}/execute`, {
|
|
97
|
+
input,
|
|
98
|
+
messages,
|
|
99
|
+
conversation_id: conversationId,
|
|
100
|
+
});
|
|
101
|
+
return res.data;
|
|
65
102
|
});
|
|
66
|
-
return response.data;
|
|
67
103
|
}
|
|
68
104
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
105
|
+
/** Fetch recent logs for an agent. */
|
|
106
|
+
async logs(agentId: string, limit: number = 100): Promise<string[]> {
|
|
107
|
+
return this.request(async () => {
|
|
108
|
+
const res = await this.http.get<{ logs: string[] }>(`/agents/${agentId}/logs`, {
|
|
109
|
+
params: { limit },
|
|
110
|
+
});
|
|
111
|
+
return res.data.logs;
|
|
72
112
|
});
|
|
73
|
-
return response.data;
|
|
74
113
|
}
|
|
75
114
|
}
|
|
76
|
-
|
|
77
|
-
export interface AgentConfig {
|
|
78
|
-
system_prompt?: string;
|
|
79
|
-
temperature?: number;
|
|
80
|
-
max_tokens?: number;
|
|
81
|
-
tools?: string[];
|
|
82
|
-
[key: string]: any;
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
export interface AgentCreate {
|
|
86
|
-
workspace_id: string; // UUID
|
|
87
|
-
name: string;
|
|
88
|
-
description?: string;
|
|
89
|
-
model_id?: string; // UUID
|
|
90
|
-
config?: AgentConfig;
|
|
91
|
-
}
|
package/src/lib/base.ts
ADDED
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
import axios, { AxiosInstance, AxiosError, AxiosRequestConfig } from 'axios';
|
|
2
|
+
|
|
3
|
+
// ── Shared Configuration ───────────────────────────────────────────────────
|
|
4
|
+
|
|
5
|
+
/** Configuration for all Langtrain SDK clients. */
|
|
6
|
+
export interface ClientConfig {
|
|
7
|
+
/** Your Langtrain API key. */
|
|
8
|
+
apiKey: string;
|
|
9
|
+
/** Override the default API base URL. */
|
|
10
|
+
baseUrl?: string;
|
|
11
|
+
/** Request timeout in milliseconds (default: 30000). */
|
|
12
|
+
timeout?: number;
|
|
13
|
+
/** Maximum number of retries on transient errors (default: 2). */
|
|
14
|
+
maxRetries?: number;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const DEFAULT_BASE_URL = 'https://api.langtrain.ai/api/v1';
|
|
18
|
+
const DEFAULT_TIMEOUT = 30_000;
|
|
19
|
+
const DEFAULT_MAX_RETRIES = 2;
|
|
20
|
+
const RETRYABLE_STATUS_CODES = [408, 429, 500, 502, 503, 504];
|
|
21
|
+
|
|
22
|
+
// ── Custom Error ───────────────────────────────────────────────────────────
|
|
23
|
+
|
|
24
|
+
export class LangtrainError extends Error {
|
|
25
|
+
/** HTTP status code, if available. */
|
|
26
|
+
readonly status?: number;
|
|
27
|
+
/** Raw error code from the API. */
|
|
28
|
+
readonly code?: string;
|
|
29
|
+
/** The original error, if any. */
|
|
30
|
+
readonly cause?: Error;
|
|
31
|
+
|
|
32
|
+
constructor(message: string, options?: { status?: number; code?: string; cause?: Error }) {
|
|
33
|
+
super(message);
|
|
34
|
+
this.name = 'LangtrainError';
|
|
35
|
+
this.status = options?.status;
|
|
36
|
+
this.code = options?.code;
|
|
37
|
+
this.cause = options?.cause;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/** True if the error was a network/timeout issue (retryable). */
|
|
41
|
+
get isTransient(): boolean {
|
|
42
|
+
return this.code === 'ECONNABORTED' || this.code === 'NETWORK_ERROR' ||
|
|
43
|
+
(this.status !== undefined && RETRYABLE_STATUS_CODES.includes(this.status));
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/** True if the API key was invalid or expired. */
|
|
47
|
+
get isAuthError(): boolean {
|
|
48
|
+
return this.status === 401 || this.status === 403;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/** True if a resource was not found. */
|
|
52
|
+
get isNotFound(): boolean {
|
|
53
|
+
return this.status === 404;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/** True if rate-limited. */
|
|
57
|
+
get isRateLimited(): boolean {
|
|
58
|
+
return this.status === 429;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// ── Base Client ────────────────────────────────────────────────────────────
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* BaseClient — abstract foundation for all Langtrain SDK clients.
|
|
66
|
+
*
|
|
67
|
+
* Provides:
|
|
68
|
+
* - Shared axios instance with API key auth
|
|
69
|
+
* - Configurable timeouts
|
|
70
|
+
* - Automatic retry with exponential backoff on transient errors
|
|
71
|
+
* - Structured error wrapping (LangtrainError)
|
|
72
|
+
*/
|
|
73
|
+
export abstract class BaseClient {
|
|
74
|
+
protected readonly http: AxiosInstance;
|
|
75
|
+
protected readonly maxRetries: number;
|
|
76
|
+
|
|
77
|
+
constructor(config: ClientConfig) {
|
|
78
|
+
this.maxRetries = config.maxRetries ?? DEFAULT_MAX_RETRIES;
|
|
79
|
+
|
|
80
|
+
this.http = axios.create({
|
|
81
|
+
baseURL: config.baseUrl || DEFAULT_BASE_URL,
|
|
82
|
+
timeout: config.timeout ?? DEFAULT_TIMEOUT,
|
|
83
|
+
headers: {
|
|
84
|
+
'X-API-Key': config.apiKey,
|
|
85
|
+
'Content-Type': 'application/json',
|
|
86
|
+
},
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Execute a request with automatic retry and error wrapping.
|
|
92
|
+
*/
|
|
93
|
+
protected async request<T>(fn: () => Promise<T>): Promise<T> {
|
|
94
|
+
let lastError: LangtrainError | undefined;
|
|
95
|
+
|
|
96
|
+
for (let attempt = 0; attempt <= this.maxRetries; attempt++) {
|
|
97
|
+
try {
|
|
98
|
+
return await fn();
|
|
99
|
+
} catch (error) {
|
|
100
|
+
lastError = this.wrapError(error);
|
|
101
|
+
|
|
102
|
+
// Only retry on transient errors, and not on the last attempt
|
|
103
|
+
if (!lastError.isTransient || attempt === this.maxRetries) {
|
|
104
|
+
throw lastError;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// Exponential backoff: 500ms, 1000ms, 2000ms...
|
|
108
|
+
const delay = Math.min(500 * Math.pow(2, attempt), 5000);
|
|
109
|
+
await this.sleep(delay);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
throw lastError!;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Wrap any thrown error into a structured LangtrainError.
|
|
118
|
+
*/
|
|
119
|
+
private wrapError(error: unknown): LangtrainError {
|
|
120
|
+
if (error instanceof LangtrainError) return error;
|
|
121
|
+
|
|
122
|
+
if (error instanceof AxiosError) {
|
|
123
|
+
const status = error.response?.status;
|
|
124
|
+
const data = error.response?.data as Record<string, unknown> | undefined;
|
|
125
|
+
const serverMessage = data?.detail ?? data?.message ?? data?.error;
|
|
126
|
+
|
|
127
|
+
const message = serverMessage
|
|
128
|
+
? String(serverMessage)
|
|
129
|
+
: error.code === 'ECONNABORTED'
|
|
130
|
+
? `Request timed out`
|
|
131
|
+
: status
|
|
132
|
+
? `API request failed with status ${status}`
|
|
133
|
+
: `Network error: ${error.message}`;
|
|
134
|
+
|
|
135
|
+
return new LangtrainError(message, {
|
|
136
|
+
status,
|
|
137
|
+
code: error.code,
|
|
138
|
+
cause: error,
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
if (error instanceof Error) {
|
|
143
|
+
return new LangtrainError(error.message, { cause: error });
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
return new LangtrainError(String(error));
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
private sleep(ms: number): Promise<void> {
|
|
150
|
+
return new Promise(resolve => setTimeout(resolve, ms));
|
|
151
|
+
}
|
|
152
|
+
}
|
package/src/lib/files.ts
CHANGED
|
@@ -1,53 +1,68 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { BaseClient, ClientConfig } from './base';
|
|
2
2
|
import FormData from 'form-data';
|
|
3
3
|
import fs from 'fs';
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
private client: AxiosInstance;
|
|
5
|
+
// ── Types ──────────────────────────────────────────────────────────────────
|
|
7
6
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
7
|
+
export interface FileResponse {
|
|
8
|
+
id: string;
|
|
9
|
+
filename: string;
|
|
10
|
+
purpose: string;
|
|
11
|
+
bytes: number;
|
|
12
|
+
created_at: string;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
// ── Client ─────────────────────────────────────────────────────────────────
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Client for managing file uploads (datasets for fine-tuning).
|
|
19
|
+
*
|
|
20
|
+
* @example
|
|
21
|
+
* ```ts
|
|
22
|
+
* const files = new FileClient({ apiKey: 'lt_...' });
|
|
23
|
+
* const uploaded = await files.upload('./data.jsonl');
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
26
|
+
export class FileClient extends BaseClient {
|
|
27
|
+
constructor(config: ClientConfig) {
|
|
28
|
+
super(config);
|
|
15
29
|
}
|
|
16
30
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
if (!fs.existsSync(file)) throw new Error(`File not found: ${file}`);
|
|
22
|
-
form.append('file', fs.createReadStream(file));
|
|
23
|
-
} else {
|
|
24
|
-
// Handle buffer or other types if needed, but for now strict to path
|
|
25
|
-
throw new Error('File path required');
|
|
31
|
+
/** Upload a file from a local path. */
|
|
32
|
+
async upload(filePath: string, workspaceId?: string, purpose: string = 'fine-tune'): Promise<FileResponse> {
|
|
33
|
+
if (!fs.existsSync(filePath)) {
|
|
34
|
+
throw new Error(`File not found: ${filePath}`);
|
|
26
35
|
}
|
|
27
36
|
|
|
28
|
-
|
|
29
|
-
|
|
37
|
+
return this.request(async () => {
|
|
38
|
+
const form = new FormData();
|
|
39
|
+
form.append('file', fs.createReadStream(filePath));
|
|
40
|
+
if (workspaceId) form.append('workspace_id', workspaceId);
|
|
41
|
+
form.append('purpose', purpose);
|
|
30
42
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
43
|
+
const res = await this.http.post<FileResponse>('/files', form, {
|
|
44
|
+
headers: form.getHeaders(),
|
|
45
|
+
maxContentLength: Infinity,
|
|
46
|
+
maxBodyLength: Infinity,
|
|
47
|
+
});
|
|
48
|
+
return res.data;
|
|
35
49
|
});
|
|
36
|
-
return response.data;
|
|
37
50
|
}
|
|
38
51
|
|
|
52
|
+
/** List files in a workspace, optionally filtered by purpose. */
|
|
39
53
|
async list(workspaceId: string, purpose?: string): Promise<FileResponse[]> {
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
54
|
+
return this.request(async () => {
|
|
55
|
+
const params: Record<string, string> = { workspace_id: workspaceId };
|
|
56
|
+
if (purpose) params.purpose = purpose;
|
|
57
|
+
const res = await this.http.get<{ data: FileResponse[] }>('/files', { params });
|
|
58
|
+
return res.data.data;
|
|
59
|
+
});
|
|
44
60
|
}
|
|
45
|
-
}
|
|
46
61
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
62
|
+
/** Delete a file by ID. */
|
|
63
|
+
async delete(fileId: string): Promise<void> {
|
|
64
|
+
return this.request(async () => {
|
|
65
|
+
await this.http.delete(`/files/${fileId}`);
|
|
66
|
+
});
|
|
67
|
+
}
|
|
53
68
|
}
|
package/src/lib/guardrails.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { BaseClient, ClientConfig } from './base';
|
|
2
|
+
|
|
3
|
+
// ── Types ──────────────────────────────────────────────────────────────────
|
|
2
4
|
|
|
3
5
|
export interface GuardrailConfig {
|
|
4
6
|
pii_enabled: boolean;
|
|
@@ -28,45 +30,73 @@ export interface GuardrailCreate {
|
|
|
28
30
|
config: GuardrailConfig;
|
|
29
31
|
}
|
|
30
32
|
|
|
31
|
-
export
|
|
32
|
-
|
|
33
|
+
export interface GuardrailApplyResult {
|
|
34
|
+
total_rows: number;
|
|
35
|
+
passed: number;
|
|
36
|
+
failed: number;
|
|
37
|
+
violations: Array<{ row: number; rule: string; message: string }>;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// ── Client ─────────────────────────────────────────────────────────────────
|
|
33
41
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
+
/**
|
|
43
|
+
* Client for managing data guardrails (PII, profanity, length, regex).
|
|
44
|
+
*
|
|
45
|
+
* @example
|
|
46
|
+
* ```ts
|
|
47
|
+
* const guardrails = new GuardrailClient({ apiKey: 'lt_...' });
|
|
48
|
+
* const rule = await guardrails.create({
|
|
49
|
+
* name: 'PII Filter',
|
|
50
|
+
* config: { pii_enabled: true, profanity_enabled: false },
|
|
51
|
+
* });
|
|
52
|
+
* ```
|
|
53
|
+
*/
|
|
54
|
+
export class GuardrailClient extends BaseClient {
|
|
55
|
+
constructor(config: ClientConfig) {
|
|
56
|
+
super(config);
|
|
42
57
|
}
|
|
43
58
|
|
|
59
|
+
/** List guardrails, optionally filtered by workspace. */
|
|
44
60
|
async list(workspaceId?: string): Promise<Guardrail[]> {
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
61
|
+
return this.request(async () => {
|
|
62
|
+
const params: Record<string, string> = {};
|
|
63
|
+
if (workspaceId) params.workspace_id = workspaceId;
|
|
64
|
+
const res = await this.http.get<Guardrail[]>('/guardrails/', { params });
|
|
65
|
+
return res.data;
|
|
66
|
+
});
|
|
49
67
|
}
|
|
50
68
|
|
|
69
|
+
/** Get a guardrail by ID. */
|
|
51
70
|
async get(guardrailId: string): Promise<Guardrail> {
|
|
52
|
-
|
|
53
|
-
|
|
71
|
+
return this.request(async () => {
|
|
72
|
+
const res = await this.http.get<Guardrail>(`/guardrails/${guardrailId}`);
|
|
73
|
+
return res.data;
|
|
74
|
+
});
|
|
54
75
|
}
|
|
55
76
|
|
|
77
|
+
/** Create a new guardrail. */
|
|
56
78
|
async create(data: GuardrailCreate): Promise<Guardrail> {
|
|
57
|
-
|
|
58
|
-
|
|
79
|
+
return this.request(async () => {
|
|
80
|
+
const res = await this.http.post<Guardrail>('/guardrails/', data);
|
|
81
|
+
return res.data;
|
|
82
|
+
});
|
|
59
83
|
}
|
|
60
84
|
|
|
85
|
+
/** Delete a guardrail by ID. */
|
|
61
86
|
async delete(guardrailId: string): Promise<void> {
|
|
62
|
-
|
|
87
|
+
return this.request(async () => {
|
|
88
|
+
await this.http.delete(`/guardrails/${guardrailId}`);
|
|
89
|
+
});
|
|
63
90
|
}
|
|
64
91
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
92
|
+
/** Apply a guardrail to a dataset for validation. */
|
|
93
|
+
async apply(datasetId: string, guardrailId: string): Promise<GuardrailApplyResult> {
|
|
94
|
+
return this.request(async () => {
|
|
95
|
+
const res = await this.http.post<GuardrailApplyResult>('/guardrails/apply', {
|
|
96
|
+
dataset_id: datasetId,
|
|
97
|
+
guardrail_id: guardrailId,
|
|
98
|
+
});
|
|
99
|
+
return res.data;
|
|
69
100
|
});
|
|
70
|
-
return response.data;
|
|
71
101
|
}
|
|
72
102
|
}
|
package/src/lib/models.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { BaseClient, ClientConfig } from './base';
|
|
2
|
+
|
|
3
|
+
// ── Types ──────────────────────────────────────────────────────────────────
|
|
2
4
|
|
|
3
5
|
export interface Permission {
|
|
4
6
|
id: string;
|
|
@@ -11,13 +13,13 @@ export interface Permission {
|
|
|
11
13
|
allow_view: boolean;
|
|
12
14
|
allow_fine_tuning: boolean;
|
|
13
15
|
organization: string;
|
|
14
|
-
group:
|
|
16
|
+
group: string | null;
|
|
15
17
|
is_blocking: boolean;
|
|
16
18
|
}
|
|
17
19
|
|
|
18
20
|
export interface Model {
|
|
19
21
|
id: string;
|
|
20
|
-
object: string;
|
|
22
|
+
object: string;
|
|
21
23
|
created: number;
|
|
22
24
|
owned_by: string;
|
|
23
25
|
permission: Permission[];
|
|
@@ -26,36 +28,38 @@ export interface Model {
|
|
|
26
28
|
task?: 'text' | 'vision' | 'agent';
|
|
27
29
|
}
|
|
28
30
|
|
|
29
|
-
|
|
30
|
-
private client: AxiosInstance;
|
|
31
|
+
// ── Client ─────────────────────────────────────────────────────────────────
|
|
31
32
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
33
|
+
/**
|
|
34
|
+
* Client for browsing available base models.
|
|
35
|
+
*
|
|
36
|
+
* @example
|
|
37
|
+
* ```ts
|
|
38
|
+
* const models = new ModelClient({ apiKey: 'lt_...' });
|
|
39
|
+
* const all = await models.list();
|
|
40
|
+
* const textModels = await models.list('text');
|
|
41
|
+
* ```
|
|
42
|
+
*/
|
|
43
|
+
export class ModelClient extends BaseClient {
|
|
44
|
+
constructor(config: ClientConfig) {
|
|
45
|
+
super(config);
|
|
40
46
|
}
|
|
41
47
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
const
|
|
48
|
-
return
|
|
49
|
-
}
|
|
50
|
-
// Fallback if endpoint doesn't support filtering or fails
|
|
51
|
-
// Verify if /models exists, otherwise return empty or throw
|
|
52
|
-
// customized error handling could go here
|
|
53
|
-
throw error;
|
|
54
|
-
}
|
|
48
|
+
/** List available models, optionally filtered by task type. */
|
|
49
|
+
async list(task?: 'text' | 'vision' | 'agent'): Promise<Model[]> {
|
|
50
|
+
return this.request(async () => {
|
|
51
|
+
const params: Record<string, string> = {};
|
|
52
|
+
if (task) params.task = task;
|
|
53
|
+
const res = await this.http.get<{ data: Model[] }>('/models', { params });
|
|
54
|
+
return res.data.data;
|
|
55
|
+
});
|
|
55
56
|
}
|
|
56
57
|
|
|
58
|
+
/** Get a specific model by ID. */
|
|
57
59
|
async get(modelId: string): Promise<Model> {
|
|
58
|
-
|
|
59
|
-
|
|
60
|
+
return this.request(async () => {
|
|
61
|
+
const res = await this.http.get<Model>(`/models/${modelId}`);
|
|
62
|
+
return res.data;
|
|
63
|
+
});
|
|
60
64
|
}
|
|
61
65
|
}
|