langwatch 1.19.0 → 2.0.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/README.md +27 -13
- package/dist/agent/index.d.mts +122 -79
- package/dist/agent/index.d.ts +122 -79
- package/dist/agent/index.js +541 -301
- package/dist/agent/index.js.map +1 -1
- package/dist/agent/index.mjs +540 -302
- package/dist/agent/index.mjs.map +1 -1
- package/dist/{chunk-NPEK4RSD.mjs → chunk-2GKEMCKT.mjs} +7757 -2409
- package/dist/chunk-2GKEMCKT.mjs.map +1 -0
- package/dist/chunk-5VYEG3RS.js +117 -0
- package/dist/chunk-5VYEG3RS.js.map +1 -0
- package/dist/chunk-AYPQNLCC.mjs +852 -0
- package/dist/chunk-AYPQNLCC.mjs.map +1 -0
- package/dist/chunk-BL3GHEKF.js +59 -0
- package/dist/chunk-BL3GHEKF.js.map +1 -0
- package/dist/chunk-C7IWJ2GJ.mjs +59 -0
- package/dist/chunk-C7IWJ2GJ.mjs.map +1 -0
- package/dist/chunk-DLZCOUXC.js +852 -0
- package/dist/chunk-DLZCOUXC.js.map +1 -0
- package/dist/{chunk-O4J3ZPZY.js → chunk-F7BVJW3S.js} +7912 -2564
- package/dist/chunk-F7BVJW3S.js.map +1 -0
- package/dist/{chunk-SY5HSL5G.mjs → chunk-M3DSPR5S.mjs} +124 -112
- package/dist/chunk-M3DSPR5S.mjs.map +1 -0
- package/dist/{chunk-CSV7B7B5.js → chunk-MAO3SIBB.js} +141 -129
- package/dist/chunk-MAO3SIBB.js.map +1 -0
- package/dist/{chunk-LCG5Y2EG.js → chunk-N76BG37W.js} +15 -101
- package/dist/chunk-N76BG37W.js.map +1 -0
- package/dist/chunk-SERULD4Z.mjs +117 -0
- package/dist/chunk-SERULD4Z.mjs.map +1 -0
- package/dist/{chunk-73QOHSHU.js → chunk-WDUUAIG3.js} +2 -2
- package/dist/chunk-WDUUAIG3.js.map +1 -0
- package/dist/{chunk-WMDQVWA6.mjs → chunk-WSGVZ3J2.mjs} +22 -108
- package/dist/chunk-WSGVZ3J2.mjs.map +1 -0
- package/dist/{chunk-57L2K66L.mjs → chunk-XQ4CP2JK.mjs} +2 -2
- package/dist/chunk-XQ4CP2JK.mjs.map +1 -0
- package/dist/cli/bundle.js +853 -552
- package/dist/implementation-BXVPzwOt.d.mts +261 -0
- package/dist/implementation-DJ-JveZl.d.ts +261 -0
- package/dist/index.d.mts +479 -1130
- package/dist/index.d.ts +479 -1130
- package/dist/index.js +7908 -3525
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +7883 -3500
- package/dist/index.mjs.map +1 -1
- package/dist/observability-sdk/index.d.mts +16 -76
- package/dist/observability-sdk/index.d.ts +16 -76
- package/dist/observability-sdk/index.js +8 -5
- package/dist/observability-sdk/index.js.map +1 -1
- package/dist/observability-sdk/index.mjs +13 -10
- package/dist/observability-sdk/instrumentation/langchain/index.d.mts +3 -5
- package/dist/observability-sdk/instrumentation/langchain/index.d.ts +3 -5
- package/dist/observability-sdk/instrumentation/langchain/index.js +160 -112
- package/dist/observability-sdk/instrumentation/langchain/index.js.map +1 -1
- package/dist/observability-sdk/instrumentation/langchain/index.mjs +148 -100
- package/dist/observability-sdk/instrumentation/langchain/index.mjs.map +1 -1
- package/dist/observability-sdk/semconv/index.d.mts +37 -0
- package/dist/observability-sdk/semconv/index.d.ts +37 -0
- package/dist/observability-sdk/semconv/index.js +121 -0
- package/dist/observability-sdk/semconv/index.js.map +1 -0
- package/dist/observability-sdk/semconv/index.mjs +121 -0
- package/dist/observability-sdk/semconv/index.mjs.map +1 -0
- package/dist/observability-sdk/setup/node/index.d.mts +73 -313
- package/dist/observability-sdk/setup/node/index.d.ts +73 -313
- package/dist/observability-sdk/setup/node/index.js +6 -4
- package/dist/observability-sdk/setup/node/index.js.map +1 -1
- package/dist/observability-sdk/setup/node/index.mjs +5 -3
- package/dist/types--ExXvd26.d.mts +16583 -0
- package/dist/{types-VOZv9LYO.d.ts → types-CoS5PmeU.d.mts} +22 -59
- package/dist/{types-VOZv9LYO.d.mts → types-CoS5PmeU.d.ts} +22 -59
- package/dist/types-CpT3iEIj.d.ts +16583 -0
- package/dist/{types-DLfhJb38.d.mts → types-RkiBQZ9j.d.mts} +1 -6
- package/dist/{types-DLfhJb38.d.ts → types-RkiBQZ9j.d.ts} +1 -6
- package/dist/values-1yj9l0Sa.d.mts +112 -0
- package/dist/values-1yj9l0Sa.d.ts +112 -0
- package/package.json +94 -64
- package/dist/chunk-57L2K66L.mjs.map +0 -1
- package/dist/chunk-73QOHSHU.js.map +0 -1
- package/dist/chunk-CSV7B7B5.js.map +0 -1
- package/dist/chunk-LCG5Y2EG.js.map +0 -1
- package/dist/chunk-NPEK4RSD.mjs.map +0 -1
- package/dist/chunk-O4J3ZPZY.js.map +0 -1
- package/dist/chunk-PIYOJF6V.mjs +0 -566
- package/dist/chunk-PIYOJF6V.mjs.map +0 -1
- package/dist/chunk-SY5HSL5G.mjs.map +0 -1
- package/dist/chunk-WGLVIV4J.js +0 -566
- package/dist/chunk-WGLVIV4J.js.map +0 -1
- package/dist/chunk-WMDQVWA6.mjs.map +0 -1
- package/dist/implementation-CeTvnq6e.d.mts +0 -716
- package/dist/implementation-CsQrexpY.d.ts +0 -716
- package/dist/types-ofe1fAYQ.d.mts +0 -38143
- package/dist/types-wuYJPoFb.d.ts +0 -38143
package/dist/index.d.mts
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
import { L as Logger, C as ConsoleLogger, N as NoOpLogger } from './index-D7rKIGrO.mjs';
|
|
2
|
-
export { F as FilterableBatchSpanProcessor, L as LangWatchExporter, S as SpanProcessingExcludeRule, g as getLangWatchLogger, a as getLangWatchTracer } from './implementation-
|
|
2
|
+
export { F as FilterableBatchSpanProcessor, L as LangWatchExporter, S as SpanProcessingExcludeRule, g as getLangWatchLogger, a as getLangWatchTracer } from './implementation-BXVPzwOt.mjs';
|
|
3
3
|
import { z } from 'zod';
|
|
4
|
-
import { p as paths, P as PromptResponse, C as CreatePromptBody, U as UpdatePromptBody, T as TagDefinition, a as CreatedTag, o as operations, b as PromptData, F as FetchPolicy, c as Prompt, L as LangWatchSpan, d as components } from './types-ofe1fAYQ.mjs';
|
|
5
4
|
import openApiCreateClient from 'openapi-fetch';
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
5
|
+
import { p as paths, P as PromptResponse, C as CreatePromptBody, U as UpdatePromptBody, T as TagDefinition, a as CreatedTag, o as operations, b as PromptData, F as FetchPolicy, c as Prompt, L as LangWatchSpan, d as components } from './types--ExXvd26.mjs';
|
|
6
|
+
export { l as attributes } from './types-CoS5PmeU.mjs';
|
|
7
|
+
import { LangWatchHandledErrorReason, LangWatchHandledErrorShape } from '@langwatch/handled-error/langwatch-handled-error';
|
|
8
|
+
export { LangWatchHandledErrorReason, LangWatchHandledErrorShape } from '@langwatch/handled-error/langwatch-handled-error';
|
|
9
9
|
import '@opentelemetry/sdk-trace-base';
|
|
10
|
-
import '@opentelemetry/exporter-trace-otlp-http';
|
|
11
10
|
import '@opentelemetry/core';
|
|
11
|
+
import '@opentelemetry/exporter-trace-otlp-proto';
|
|
12
|
+
import '@opentelemetry/otlp-exporter-base';
|
|
12
13
|
import '@opentelemetry/api-logs';
|
|
14
|
+
import './values-1yj9l0Sa.mjs';
|
|
13
15
|
import '@opentelemetry/api';
|
|
14
|
-
import '@opentelemetry/semantic-conventions';
|
|
15
|
-
import '@opentelemetry/semantic-conventions/incubating';
|
|
16
16
|
|
|
17
17
|
declare const localPromptConfigSchema: z.ZodObject<{
|
|
18
18
|
model: z.ZodString;
|
|
@@ -28,7 +28,7 @@ declare const localPromptConfigSchema: z.ZodObject<{
|
|
|
28
28
|
}>;
|
|
29
29
|
content: z.ZodString;
|
|
30
30
|
}, z.core.$loose>>;
|
|
31
|
-
parameters: z.ZodDefault<z.ZodOptional<z.ZodRecord<z.ZodString, z.
|
|
31
|
+
parameters: z.ZodDefault<z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodJSONSchema>>>;
|
|
32
32
|
}, z.core.$loose>;
|
|
33
33
|
type LocalPromptConfig = z.infer<typeof localPromptConfigSchema>;
|
|
34
34
|
|
|
@@ -40,10 +40,9 @@ type PromptsConfig = {
|
|
|
40
40
|
prompts: Record<string, PromptDependency>;
|
|
41
41
|
};
|
|
42
42
|
/**
|
|
43
|
-
* A JSON value: what runtime parameters
|
|
44
|
-
*
|
|
45
|
-
*
|
|
46
|
-
* between hand-written and generated types without casts.
|
|
43
|
+
* A JSON value: what runtime parameters persist and the API schema declares.
|
|
44
|
+
* Structurally identical to the generated client's RecursiveJsonValue, so
|
|
45
|
+
* values flow between hand-written and generated types without casts.
|
|
47
46
|
*/
|
|
48
47
|
type JsonValue = string | number | boolean | null | JsonValue[] | {
|
|
49
48
|
[key: string]: JsonValue;
|
|
@@ -55,15 +54,15 @@ type MaterializedPrompt = {
|
|
|
55
54
|
version: number;
|
|
56
55
|
versionId: string;
|
|
57
56
|
model: string;
|
|
58
|
-
messages:
|
|
57
|
+
messages: {
|
|
59
58
|
role: "system" | "user" | "assistant";
|
|
60
59
|
content: string;
|
|
61
|
-
}
|
|
60
|
+
}[];
|
|
62
61
|
prompt: string;
|
|
63
62
|
temperature?: number;
|
|
64
63
|
maxTokens?: number;
|
|
65
|
-
inputs?:
|
|
66
|
-
outputs?:
|
|
64
|
+
inputs?: unknown;
|
|
65
|
+
outputs?: unknown;
|
|
67
66
|
parameters: RuntimeParameters;
|
|
68
67
|
updatedAt: string;
|
|
69
68
|
};
|
|
@@ -79,13 +78,8 @@ type PromptsLock = {
|
|
|
79
78
|
|
|
80
79
|
/**
|
|
81
80
|
* Creates a new LangWatch API client.
|
|
82
|
-
* @param apiKey - The API key or Personal Access Token
|
|
83
|
-
*
|
|
84
|
-
* @param endpoint - The endpoint to use for the API client. Defaults to `LANGWATCH_ENDPOINT`
|
|
85
|
-
* or the internal `DEFAULT_ENDPOINT`.
|
|
86
|
-
* @param projectId - Project identifier. Required when `apiKey` is a PAT
|
|
87
|
-
* (`pat-lw-*`). Defaults to `LANGWATCH_PROJECT_ID`.
|
|
88
|
-
* @returns A new LangWatch API client.
|
|
81
|
+
* @param apiKey - The API key or Personal Access Token. Defaults to `LANGWATCH_API_KEY`.
|
|
82
|
+
* @param endpoint - The API endpoint. Defaults to `LANGWATCH_ENDPOINT` or `DEFAULT_ENDPOINT`.
|
|
89
83
|
*/
|
|
90
84
|
declare const createLangWatchApiClient: (apiKey?: string, endpoint?: string, projectId?: string | undefined) => openApiCreateClient.Client<paths, `${string}/${string}`>;
|
|
91
85
|
type LangwatchApiClient = ReturnType<typeof createLangWatchApiClient>;
|
|
@@ -103,7 +97,7 @@ declare const syncActionSchema: z.ZodEnum<{
|
|
|
103
97
|
}>;
|
|
104
98
|
type SyncAction = z.infer<typeof syncActionSchema>;
|
|
105
99
|
type AssignTagResult = NonNullable<operations["putApiPromptsByIdTagsByTag"]["responses"]["200"]["content"]["application/json"]>;
|
|
106
|
-
type ConfigData = NonNullable<paths["/api/prompts/{id}/sync"]["post"]["requestBody"]>["content"]["application/json"]["configData"];
|
|
100
|
+
type ConfigData = NonNullable<paths["/api/v1/prompts/{id}/sync"]["post"]["requestBody"]>["content"]["application/json"]["configData"];
|
|
107
101
|
interface SyncResult {
|
|
108
102
|
action: SyncAction;
|
|
109
103
|
prompt?: PromptResponse;
|
|
@@ -116,24 +110,16 @@ interface SyncResult {
|
|
|
116
110
|
};
|
|
117
111
|
}
|
|
118
112
|
/**
|
|
119
|
-
* Service for managing prompt resources via the Langwatch API.
|
|
120
|
-
*
|
|
121
|
-
*
|
|
122
|
-
* Responsibilities:
|
|
123
|
-
* - CRUD operations for prompts
|
|
124
|
-
* - Creating prompt versions
|
|
125
|
-
* - Error handling with contextual information
|
|
126
|
-
*
|
|
127
|
-
* All methods return raw PromptResponse data from the API.
|
|
113
|
+
* Service for managing prompt resources via the Langwatch API. Constructor creates a proxy
|
|
114
|
+
* that wraps the service and traces all methods.
|
|
128
115
|
*/
|
|
129
116
|
declare class PromptsApiService {
|
|
130
117
|
private readonly apiClient;
|
|
131
118
|
constructor(config?: Pick<InternalConfig, "langwatchApiClient">);
|
|
132
119
|
/**
|
|
133
|
-
* Handles API errors by throwing a PromptsApiError with operation context.
|
|
120
|
+
* Handles API errors by throwing a PromptsApiError with operation context. @throws
|
|
134
121
|
* @param operation Description of the operation being performed.
|
|
135
122
|
* @param error The error object returned from the API client.
|
|
136
|
-
* @throws {PromptsApiError}
|
|
137
123
|
*/
|
|
138
124
|
private handleApiError;
|
|
139
125
|
/**
|
|
@@ -145,36 +131,28 @@ declare class PromptsApiService {
|
|
|
145
131
|
/**
|
|
146
132
|
* Fetches a single prompt by its ID.
|
|
147
133
|
* @param id The prompt's unique identifier.
|
|
148
|
-
* @param options Optional
|
|
149
|
-
* @param options.version Specific version to fetch (numeric string or "latest").
|
|
150
|
-
* @param options.tag Tag to fetch (e.g., "production", "staging", or a custom tag).
|
|
151
|
-
* @returns Raw PromptResponse data.
|
|
152
|
-
* @throws {PromptsApiError} If the API call fails.
|
|
134
|
+
* @param options Optional version or tag to fetch.
|
|
153
135
|
*/
|
|
154
136
|
get: (id: string, options?: {
|
|
155
137
|
version?: string;
|
|
156
138
|
tag?: string;
|
|
157
139
|
}) => Promise<PromptResponse>;
|
|
158
140
|
/**
|
|
159
|
-
* Validates if a prompt exists.
|
|
141
|
+
* Validates if a prompt exists. @throws {PromptsApiError} If the API call fails (not 404).
|
|
160
142
|
* @param id The prompt's unique identifier.
|
|
161
143
|
* @returns True if prompt exists, false otherwise.
|
|
162
|
-
* @throws {PromptsApiError} If the API call fails (not 404).
|
|
163
144
|
*/
|
|
164
145
|
exists(id: string): Promise<boolean>;
|
|
165
146
|
/**
|
|
166
|
-
* Creates a new prompt.
|
|
147
|
+
* Creates a new prompt. @throws {PromptsApiError} If the API call fails.
|
|
167
148
|
* @param params The prompt creation payload, matching the OpenAPI schema.
|
|
168
149
|
* @returns Raw PromptResponse data of the created prompt.
|
|
169
|
-
* @throws {PromptsApiError} If the API call fails.
|
|
170
150
|
*/
|
|
171
151
|
create(params: CreatePromptBody): Promise<PromptResponse>;
|
|
172
152
|
/**
|
|
173
|
-
* Updates an existing prompt.
|
|
174
153
|
* @param id The prompt's unique identifier.
|
|
175
154
|
* @param params The update payload, matching the OpenAPI schema.
|
|
176
155
|
* @returns Raw PromptResponse data of the updated prompt.
|
|
177
|
-
* @throws {PromptsApiError} If the API call fails.
|
|
178
156
|
*/
|
|
179
157
|
update(id: string, params: UpdatePromptBody): Promise<PromptResponse>;
|
|
180
158
|
/**
|
|
@@ -184,10 +162,9 @@ declare class PromptsApiService {
|
|
|
184
162
|
*/
|
|
185
163
|
listTags(): Promise<TagDefinition[]>;
|
|
186
164
|
/**
|
|
187
|
-
* Creates a custom prompt tag for the organization.
|
|
165
|
+
* Creates a custom prompt tag for the organization. @throws {PromptsApiError} If the API
|
|
188
166
|
* @param params.name The tag name (must match /^[a-z][a-z0-9_-]*$/).
|
|
189
167
|
* @returns The created tag.
|
|
190
|
-
* @throws {PromptsApiError} If the API call fails.
|
|
191
168
|
*/
|
|
192
169
|
createTag({ name }: {
|
|
193
170
|
name: string;
|
|
@@ -199,10 +176,9 @@ declare class PromptsApiService {
|
|
|
199
176
|
*/
|
|
200
177
|
deleteTag(tagName: string): Promise<void>;
|
|
201
178
|
/**
|
|
202
|
-
* Renames an existing prompt tag.
|
|
179
|
+
* Renames an existing prompt tag. @throws {PromptsApiError} If the API call fails.
|
|
203
180
|
* @param tag The current tag name.
|
|
204
181
|
* @param name The new tag name.
|
|
205
|
-
* @throws {PromptsApiError} If the API call fails.
|
|
206
182
|
*/
|
|
207
183
|
renameTag({ tag, name }: {
|
|
208
184
|
tag: string;
|
|
@@ -222,18 +198,15 @@ declare class PromptsApiService {
|
|
|
222
198
|
success: boolean;
|
|
223
199
|
}>;
|
|
224
200
|
/**
|
|
225
|
-
* Fetches all versions for a given prompt.
|
|
201
|
+
* Fetches all versions for a given prompt. @throws {PromptsApiError} If the API call
|
|
226
202
|
* @param id The prompt's unique identifier.
|
|
227
203
|
* @returns Array of raw PromptResponse data for each version.
|
|
228
|
-
* @throws {PromptsApiError} If the API call fails.
|
|
229
204
|
*/
|
|
230
205
|
getVersions(id: string): Promise<PromptResponse[]>;
|
|
231
206
|
/**
|
|
232
|
-
* Upserts a prompt with local configuration - creates if doesn't exist, updates version if exists.
|
|
233
207
|
* @param handle The prompt's handle/identifier.
|
|
234
208
|
* @param config Local prompt configuration.
|
|
235
209
|
* @returns Object with created flag and raw PromptResponse data.
|
|
236
|
-
* @throws {PromptsApiError} If the API call fails.
|
|
237
210
|
*/
|
|
238
211
|
upsert(handle: string, config: {
|
|
239
212
|
model: string;
|
|
@@ -241,10 +214,10 @@ declare class PromptsApiService {
|
|
|
241
214
|
temperature?: number;
|
|
242
215
|
max_tokens?: number;
|
|
243
216
|
};
|
|
244
|
-
messages:
|
|
217
|
+
messages: {
|
|
245
218
|
role: "system" | "user" | "assistant";
|
|
246
219
|
content: string;
|
|
247
|
-
}
|
|
220
|
+
}[];
|
|
248
221
|
parameters?: RuntimeParameters;
|
|
249
222
|
}): Promise<{
|
|
250
223
|
created: boolean;
|
|
@@ -269,15 +242,8 @@ declare class FileManager {
|
|
|
269
242
|
private static readonly PROMPTS_DIR;
|
|
270
243
|
private static readonly MATERIALIZED_DIR;
|
|
271
244
|
private static _projectRoot;
|
|
272
|
-
/**
|
|
273
|
-
*
|
|
274
|
-
*
|
|
275
|
-
* The cache MUST be keyed by it. Memoising a cwd-derived path without that key
|
|
276
|
-
* is correct only in a process that serves exactly one command and then dies;
|
|
277
|
-
* in a process that serves many from different directories (the CLI daemon, a
|
|
278
|
-
* test runner, an embedding host), the second caller silently inherits the
|
|
279
|
-
* first caller's project root and reads or writes the wrong prompts.json.
|
|
280
|
-
*/
|
|
245
|
+
/** The cwd `_projectRoot` was derived from. Cache must be keyed by it or
|
|
246
|
+
* multi-directory processes like daemons will use the wrong root. */
|
|
281
247
|
private static _projectRootCwd;
|
|
282
248
|
/** Reset the cached project root. Tests use this to exercise different cwds. */
|
|
283
249
|
static _resetProjectRootCache(): void;
|
|
@@ -320,12 +286,9 @@ interface LocalPromptsServiceConfig {
|
|
|
320
286
|
logger?: Logger;
|
|
321
287
|
}
|
|
322
288
|
/**
|
|
323
|
-
*
|
|
324
|
-
*
|
|
325
|
-
*
|
|
326
|
-
* 1. Explicit file mapping in prompts.json config
|
|
327
|
-
* 2. Materialized path from prompts-lock.json
|
|
328
|
-
* 3. Direct file scanning in prompts directory
|
|
289
|
+
* Retrieves prompts from local filesystem sources, in priority order:
|
|
290
|
+
* explicit prompts.json mapping, materialized prompts-lock.json path,
|
|
291
|
+
* then direct scanning of the prompts directory.
|
|
329
292
|
*/
|
|
330
293
|
declare class LocalPromptsService {
|
|
331
294
|
private readonly fileManager;
|
|
@@ -408,11 +371,7 @@ declare class PromptsFacade implements Pick<PromptsApiService, "sync" | "delete"
|
|
|
408
371
|
*/
|
|
409
372
|
create(data: CreatePromptBody): Promise<Prompt>;
|
|
410
373
|
/**
|
|
411
|
-
* Retrieves a prompt by handle or ID.
|
|
412
|
-
*
|
|
413
|
-
* Supports shorthand `handle:tag` syntax — e.g. `get("pizza-prompt:production")`.
|
|
414
|
-
* Shorthand is parsed server-side; the SDK passes the string through as-is.
|
|
415
|
-
*
|
|
374
|
+
* Retrieves a prompt by handle or ID (supports `handle:tag` shorthand, parsed server-side).
|
|
416
375
|
* @param handleOrId The prompt's handle, unique identifier, or `handle:tag` shorthand.
|
|
417
376
|
* @param options Optional parameters for the request.
|
|
418
377
|
* @returns The Prompt instance.
|
|
@@ -597,8 +556,8 @@ type DeleteRecordsResponse = {
|
|
|
597
556
|
deletedCount: number;
|
|
598
557
|
};
|
|
599
558
|
/**
|
|
600
|
-
* API response for uploading a file.
|
|
601
|
-
*
|
|
559
|
+
* API response for uploading a file. Covers both upload-to-existing
|
|
560
|
+
* (records) and create-from-file (recordsCreated, datasetId) responses.
|
|
602
561
|
*/
|
|
603
562
|
type UploadResponse = {
|
|
604
563
|
dataset?: DatasetMetadata;
|
|
@@ -618,7 +577,10 @@ type ListRecordsOptions = {
|
|
|
618
577
|
/**
|
|
619
578
|
* API response for listing records in a dataset.
|
|
620
579
|
*/
|
|
621
|
-
type ListRecordsApiResponse = PaginatedResponse<DatasetRecordResponse
|
|
580
|
+
type ListRecordsApiResponse = PaginatedResponse<DatasetRecordResponse> & {
|
|
581
|
+
/** The dataset the page belongs to. Absent on servers that do not send it. */
|
|
582
|
+
dataset?: DatasetMetadata;
|
|
583
|
+
};
|
|
622
584
|
/**
|
|
623
585
|
* API response for creating a dataset from a file upload.
|
|
624
586
|
*/
|
|
@@ -635,91 +597,33 @@ type DatasetsFacadeConfig = {
|
|
|
635
597
|
};
|
|
636
598
|
/**
|
|
637
599
|
* Facade for dataset operations in the LangWatch SDK.
|
|
638
|
-
* Provides a simplified interface for managing datasets, records, and file uploads.
|
|
639
|
-
*
|
|
640
600
|
* @example
|
|
641
|
-
* ```typescript
|
|
642
|
-
* const langwatch = new LangWatch({ apiKey: "your-api-key" });
|
|
643
|
-
*
|
|
644
|
-
* // List all datasets
|
|
645
601
|
* const datasets = await langwatch.datasets.list();
|
|
646
|
-
*
|
|
647
|
-
* // Get a dataset by slug or ID
|
|
648
|
-
* const dataset = await langwatch.datasets.get("my-dataset");
|
|
649
|
-
*
|
|
650
|
-
* // Create a new dataset
|
|
651
|
-
* const newDataset = await langwatch.datasets.create({
|
|
652
|
-
* name: "my-dataset",
|
|
653
|
-
* columnTypes: [{ name: "input", type: "string" }],
|
|
654
|
-
* });
|
|
655
|
-
*
|
|
656
|
-
* // Update a dataset
|
|
657
|
-
* const updated = await langwatch.datasets.update("my-dataset", { name: "new-name" });
|
|
658
|
-
*
|
|
659
|
-
* // Delete a dataset
|
|
660
|
-
* const archived = await langwatch.datasets.delete("my-dataset");
|
|
661
|
-
*
|
|
662
|
-
* // Create records
|
|
663
|
-
* const records = await langwatch.datasets.createRecords("my-dataset", [
|
|
664
|
-
* { input: "hello", output: "world" },
|
|
665
|
-
* ]);
|
|
666
|
-
*
|
|
667
|
-
* // Update a record
|
|
668
|
-
* const record = await langwatch.datasets.updateRecord("my-dataset", "rec-1", { input: "updated" });
|
|
669
|
-
*
|
|
670
|
-
* // Delete records
|
|
671
|
-
* const result = await langwatch.datasets.deleteRecords("my-dataset", ["rec-1", "rec-2"]);
|
|
672
|
-
*
|
|
673
|
-
* // Upload a file (append to existing or create new)
|
|
674
|
-
* const uploadResult = await langwatch.datasets.upload("my-dataset", file);
|
|
675
|
-
*
|
|
676
|
-
* // Upload with replace strategy (delete all records first)
|
|
677
|
-
* await langwatch.datasets.upload("my-dataset", file, { ifExists: "replace" });
|
|
678
|
-
* ```
|
|
679
602
|
*/
|
|
680
603
|
declare class DatasetsFacade {
|
|
681
604
|
#private;
|
|
682
605
|
constructor(config: DatasetsFacadeConfig);
|
|
683
606
|
/**
|
|
684
607
|
* Lists all datasets for the project, with optional pagination.
|
|
685
|
-
*
|
|
686
608
|
* @param options - Pagination options (page, limit)
|
|
687
609
|
* @returns Paginated list of datasets with metadata
|
|
688
610
|
*/
|
|
689
611
|
list: (options?: ListDatasetsOptions) => Promise<ListDatasetsApiResponse>;
|
|
690
612
|
/**
|
|
691
613
|
* Creates a new dataset.
|
|
692
|
-
*
|
|
693
614
|
* @param options - Dataset creation options (name, columnTypes)
|
|
694
615
|
* @returns The created dataset metadata
|
|
695
616
|
*/
|
|
696
617
|
create: (options: CreateDatasetOptions) => Promise<DatasetMetadata>;
|
|
697
618
|
/**
|
|
698
619
|
* Fetches a dataset by its slug or ID, returning metadata and entries.
|
|
699
|
-
*
|
|
700
620
|
* @param slugOrId - The slug or ID of the dataset to fetch
|
|
701
621
|
* @param options - Optional configuration
|
|
702
622
|
* @returns The dataset with metadata and entries
|
|
703
|
-
*
|
|
704
|
-
* @example
|
|
705
|
-
* ```typescript
|
|
706
|
-
* // Get dataset by slug
|
|
707
|
-
* const dataset = await langwatch.datasets.get("product-qa");
|
|
708
|
-
*
|
|
709
|
-
* // Typed dataset
|
|
710
|
-
* type MyDatasetEntry = { input: string; expected_output: string; };
|
|
711
|
-
* const dataset = await langwatch.datasets.get<MyDatasetEntry>("my-dataset");
|
|
712
|
-
*
|
|
713
|
-
* // Iterate over entries
|
|
714
|
-
* for (const entry of dataset.entries) {
|
|
715
|
-
* console.log(entry.entry.input);
|
|
716
|
-
* }
|
|
717
|
-
* ```
|
|
718
623
|
*/
|
|
719
624
|
get: <T extends Record<string, unknown> = Record<string, unknown>>(slugOrId: string, options?: GetDatasetOptions) => Promise<Dataset<T>>;
|
|
720
625
|
/**
|
|
721
626
|
* Updates a dataset by its slug or ID.
|
|
722
|
-
*
|
|
723
627
|
* @param slugOrId - The slug or ID of the dataset to update
|
|
724
628
|
* @param options - Fields to update (name, columnTypes)
|
|
725
629
|
* @returns The updated dataset metadata
|
|
@@ -727,14 +631,12 @@ declare class DatasetsFacade {
|
|
|
727
631
|
update: (slugOrId: string, options: UpdateDatasetOptions) => Promise<DatasetMetadata>;
|
|
728
632
|
/**
|
|
729
633
|
* Deletes (archives) a dataset by its slug or ID.
|
|
730
|
-
*
|
|
731
634
|
* @param slugOrId - The slug or ID of the dataset to delete
|
|
732
635
|
* @returns The archived dataset metadata
|
|
733
636
|
*/
|
|
734
637
|
delete: (slugOrId: string) => Promise<DatasetMetadata>;
|
|
735
638
|
/**
|
|
736
639
|
* Creates records in a dataset in batch.
|
|
737
|
-
*
|
|
738
640
|
* @param slugOrId - The slug or ID of the dataset
|
|
739
641
|
* @param entries - Array of record entries to create
|
|
740
642
|
* @returns The created records with IDs
|
|
@@ -742,7 +644,6 @@ declare class DatasetsFacade {
|
|
|
742
644
|
createRecords: (slugOrId: string, entries: Record<string, unknown>[]) => Promise<BatchCreateRecordsResponse>;
|
|
743
645
|
/**
|
|
744
646
|
* Updates a single record in a dataset.
|
|
745
|
-
*
|
|
746
647
|
* @param slugOrId - The slug or ID of the dataset
|
|
747
648
|
* @param recordId - The ID of the record to update
|
|
748
649
|
* @param entry - The updated entry data
|
|
@@ -751,7 +652,6 @@ declare class DatasetsFacade {
|
|
|
751
652
|
updateRecord: (slugOrId: string, recordId: string, entry: Record<string, unknown>) => Promise<DatasetRecordResponse>;
|
|
752
653
|
/**
|
|
753
654
|
* Deletes records from a dataset by IDs.
|
|
754
|
-
*
|
|
755
655
|
* @param slugOrId - The slug or ID of the dataset
|
|
756
656
|
* @param recordIds - Array of record IDs to delete
|
|
757
657
|
* @returns Object with the count of deleted records
|
|
@@ -759,47 +659,17 @@ declare class DatasetsFacade {
|
|
|
759
659
|
deleteRecords: (slugOrId: string, recordIds: string[]) => Promise<DeleteRecordsResponse>;
|
|
760
660
|
/**
|
|
761
661
|
* Lists records in a dataset with optional pagination.
|
|
762
|
-
*
|
|
763
662
|
* @param slugOrId - The slug or ID of the dataset
|
|
764
663
|
* @param options - Pagination options (page, limit)
|
|
765
664
|
* @returns Paginated list of records
|
|
766
|
-
*
|
|
767
|
-
* @example
|
|
768
|
-
* ```typescript
|
|
769
|
-
* // List first page of records
|
|
770
|
-
* const result = await langwatch.datasets.listRecords("my-dataset");
|
|
771
|
-
*
|
|
772
|
-
* // With pagination
|
|
773
|
-
* const page2 = await langwatch.datasets.listRecords("my-dataset", { page: 2, limit: 25 });
|
|
774
|
-
* ```
|
|
775
665
|
*/
|
|
776
666
|
listRecords: (slugOrId: string, options?: ListRecordsOptions) => Promise<ListRecordsApiResponse>;
|
|
777
667
|
/**
|
|
778
|
-
* Uploads a file to a dataset with a
|
|
779
|
-
*
|
|
780
|
-
* Strategies:
|
|
781
|
-
* - `"append"` (default): Upload to existing dataset; if not found, create a new one.
|
|
782
|
-
* - `"replace"`: Delete all existing records, then upload; if not found, create a new one.
|
|
783
|
-
* - `"error"`: Throw a 409 error if the dataset already exists; if not found, create a new one.
|
|
784
|
-
*
|
|
668
|
+
* Uploads a file to a dataset with a strategy for existing datasets (default "append").
|
|
785
669
|
* @param slugOrId - The slug or ID of the dataset
|
|
786
670
|
* @param file - The file to upload (File or Blob)
|
|
787
671
|
* @param options - Upload options including the ifExists strategy
|
|
788
672
|
* @returns The upload result
|
|
789
|
-
*
|
|
790
|
-
* @example
|
|
791
|
-
* ```typescript
|
|
792
|
-
* const file = new File(["input,output\nhello,world"], "data.csv", { type: "text/csv" });
|
|
793
|
-
*
|
|
794
|
-
* // Append to existing or create new
|
|
795
|
-
* await langwatch.datasets.upload("my-dataset", file);
|
|
796
|
-
*
|
|
797
|
-
* // Replace all records
|
|
798
|
-
* await langwatch.datasets.upload("my-dataset", file, { ifExists: "replace" });
|
|
799
|
-
*
|
|
800
|
-
* // Fail if dataset already exists
|
|
801
|
-
* await langwatch.datasets.upload("my-dataset", file, { ifExists: "error" });
|
|
802
|
-
* ```
|
|
803
673
|
*/
|
|
804
674
|
upload: (slugOrId: string, file: File | Blob, options?: {
|
|
805
675
|
ifExists?: "append" | "replace" | "error";
|
|
@@ -851,15 +721,12 @@ declare class DatasetPlanLimitError extends DatasetError {
|
|
|
851
721
|
|
|
852
722
|
/**
|
|
853
723
|
* Types for the Experiments API
|
|
854
|
-
*
|
|
855
|
-
* These types define the structure for batch experiments, including
|
|
856
|
-
* logging metrics, running evaluators, and managing targets.
|
|
857
724
|
*/
|
|
858
725
|
|
|
859
726
|
/**
|
|
860
727
|
* Status of an evaluation result
|
|
861
728
|
*/
|
|
862
|
-
type
|
|
729
|
+
type ExperimentEvaluationStatus = "processed" | "error" | "skipped";
|
|
863
730
|
/**
|
|
864
731
|
* Target types for batch evaluations
|
|
865
732
|
*/
|
|
@@ -872,9 +739,9 @@ declare const targetInfoSchema: z.ZodObject<{
|
|
|
872
739
|
id: z.ZodString;
|
|
873
740
|
name: z.ZodString;
|
|
874
741
|
type: z.ZodDefault<z.ZodEnum<{
|
|
742
|
+
prompt: "prompt";
|
|
875
743
|
custom: "custom";
|
|
876
744
|
agent: "agent";
|
|
877
|
-
prompt: "prompt";
|
|
878
745
|
}>>;
|
|
879
746
|
metadata: z.ZodOptional<z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean]>>>>;
|
|
880
747
|
}, z.core.$strip>;
|
|
@@ -884,8 +751,8 @@ declare const evaluationResultSchema: z.ZodObject<{
|
|
|
884
751
|
trace_id: z.ZodString;
|
|
885
752
|
status: z.ZodEnum<{
|
|
886
753
|
error: "error";
|
|
887
|
-
processed: "processed";
|
|
888
754
|
skipped: "skipped";
|
|
755
|
+
processed: "processed";
|
|
889
756
|
}>;
|
|
890
757
|
data: z.ZodOptional<z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
|
|
891
758
|
score: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
|
|
@@ -906,7 +773,7 @@ type TargetInfo = z.infer<typeof targetInfoSchema>;
|
|
|
906
773
|
/**
|
|
907
774
|
* Result of an evaluation
|
|
908
775
|
*/
|
|
909
|
-
type
|
|
776
|
+
type ExperimentEvaluationResult = z.infer<typeof evaluationResultSchema>;
|
|
910
777
|
/**
|
|
911
778
|
* Options for initializing an experiment
|
|
912
779
|
*/
|
|
@@ -936,7 +803,7 @@ type LogOptions = {
|
|
|
936
803
|
/** Human-readable description of the result */
|
|
937
804
|
details?: string;
|
|
938
805
|
/** Status of the evaluation */
|
|
939
|
-
status?:
|
|
806
|
+
status?: ExperimentEvaluationStatus;
|
|
940
807
|
/** Duration in milliseconds */
|
|
941
808
|
duration?: number;
|
|
942
809
|
/** Cost amount in USD */
|
|
@@ -954,7 +821,7 @@ type LogOptions = {
|
|
|
954
821
|
/**
|
|
955
822
|
* Options for the evaluate() method (built-in evaluators)
|
|
956
823
|
*/
|
|
957
|
-
type
|
|
824
|
+
type ExperimentEvaluateOptions = {
|
|
958
825
|
/**
|
|
959
826
|
* Row index in the dataset.
|
|
960
827
|
* Optional when called inside withTarget() - will be auto-inferred from context.
|
|
@@ -978,25 +845,10 @@ type EvaluateOptions$1 = {
|
|
|
978
845
|
};
|
|
979
846
|
/**
|
|
980
847
|
* Per-candidate metric the judge can be asked to weigh alongside quality
|
|
981
|
-
*
|
|
982
|
-
* Duration is the one the SDK measures itself. Cost is not on offer: the
|
|
983
|
-
* platform works a target's cost out from its traces after the run, so there
|
|
984
|
-
* is nothing to show the judge at the moment a verdict is asked for.
|
|
985
848
|
*/
|
|
986
849
|
type ComparisonMetric = "duration";
|
|
987
850
|
/**
|
|
988
851
|
* Outcome of a comparison
|
|
989
|
-
*
|
|
990
|
-
* - `decided`: the judge picked a winner
|
|
991
|
-
* - `tie`: the judge judged the candidates and found none clearly better
|
|
992
|
-
* - `inconclusive`: the judge judged the candidates and established no winner,
|
|
993
|
-
* which under swap-and-reconcile means its two passes disagreed. A finding
|
|
994
|
-
* about the candidates, and not a tie: a tie is a measurement, this is the
|
|
995
|
-
* absence of one
|
|
996
|
-
* - `skipped`: fewer than two targets had an output, so no judge ran
|
|
997
|
-
* - `error`: the judge could not be reached or failed, so nothing was measured
|
|
998
|
-
* about the candidates at all. Never conflated with `inconclusive`, which
|
|
999
|
-
* says something about them
|
|
1000
852
|
*/
|
|
1001
853
|
type ComparisonStatus = "decided" | "tie" | "inconclusive" | "skipped" | "error";
|
|
1002
854
|
/**
|
|
@@ -1017,20 +869,10 @@ type ComparisonVerdict = {
|
|
|
1017
869
|
};
|
|
1018
870
|
/**
|
|
1019
871
|
* Options for the compare() method
|
|
1020
|
-
*
|
|
1021
|
-
* Every option below is optional because the judge already has a default for
|
|
1022
|
-
* it. An option left unset is absent from the request, so the judge's own
|
|
1023
|
-
* default applies and there is exactly one place where each default is
|
|
1024
|
-
* written down. The defaults are documented here for reference only, and are
|
|
1025
|
-
* deliberately not restated in code.
|
|
1026
872
|
*/
|
|
1027
873
|
type ComparisonOptions = {
|
|
1028
874
|
/**
|
|
1029
|
-
* Row index in the dataset. Also seeds the judge's deterministic candidate
|
|
1030
|
-
* shuffle.
|
|
1031
|
-
*
|
|
1032
|
-
* compare() takes the row the way log() does: inside a run() callback it is
|
|
1033
|
-
* inferred from the row being processed, and outside one it is required.
|
|
875
|
+
* Row index in the dataset. Also seeds the judge's deterministic candidate shuffle.
|
|
1034
876
|
*/
|
|
1035
877
|
index?: number;
|
|
1036
878
|
/** Name the verdict is recorded under (default: "comparison") */
|
|
@@ -1130,13 +972,6 @@ type TargetResult<R> = {
|
|
|
1130
972
|
|
|
1131
973
|
/**
|
|
1132
974
|
* Experiment - Main class for running batch experiments
|
|
1133
|
-
*
|
|
1134
|
-
* Provides a clean API for running experiments over datasets with:
|
|
1135
|
-
* - Automatic tracing per iteration
|
|
1136
|
-
* - Parallel execution with concurrency control
|
|
1137
|
-
* - Batched result sending
|
|
1138
|
-
* - Built-in evaluator support
|
|
1139
|
-
* - Multi-target comparison with withTarget() context isolation
|
|
1140
975
|
*/
|
|
1141
976
|
|
|
1142
977
|
/**
|
|
@@ -1158,6 +993,9 @@ declare class Experiment {
|
|
|
1158
993
|
private batch;
|
|
1159
994
|
private lastSentMs;
|
|
1160
995
|
private pendingFlush;
|
|
996
|
+
/** Every row and verdict sent so far, by the identity the platform stores it under. */
|
|
997
|
+
private readonly sentRows;
|
|
998
|
+
private readonly sentEvaluations;
|
|
1161
999
|
private flushTimeout;
|
|
1162
1000
|
private cumulativeEvaluations;
|
|
1163
1001
|
private cumulativeEntries;
|
|
@@ -1181,44 +1019,23 @@ declare class Experiment {
|
|
|
1181
1019
|
*/
|
|
1182
1020
|
private initialize;
|
|
1183
1021
|
/**
|
|
1184
|
-
* Run evaluation over a dataset with a callback
|
|
1185
|
-
*
|
|
1022
|
+
* Run evaluation over a dataset with a callback.
|
|
1186
1023
|
* @param dataset - Array of items to evaluate
|
|
1187
1024
|
* @param callback - Function called for each item with { item, index, span }
|
|
1188
|
-
* @param options - Concurrency options
|
|
1189
|
-
*
|
|
1190
|
-
* @example
|
|
1191
|
-
* ```typescript
|
|
1192
|
-
* await evaluation.run(dataset, async ({ item, index, span }) => {
|
|
1193
|
-
* const response = await myAgent(item.question);
|
|
1194
|
-
* evaluation.log('accuracy', { index, score: 0.95 });
|
|
1195
|
-
* }, { concurrency: 4 });
|
|
1196
|
-
* ```
|
|
1197
1025
|
*/
|
|
1198
1026
|
run<T>(dataset: T[], callback: RunCallback<T>, options?: RunOptions): Promise<void>;
|
|
1199
1027
|
/**
|
|
1200
1028
|
* Execute a single item in the dataset
|
|
1201
1029
|
*/
|
|
1030
|
+
/** Runs one row without a trace of its own: each withTarget() call traces itself. */
|
|
1031
|
+
private runItemUntraced;
|
|
1032
|
+
/** Runs one row inside its own iteration span. */
|
|
1033
|
+
private runItemTraced;
|
|
1202
1034
|
private executeItem;
|
|
1203
1035
|
/**
|
|
1204
|
-
* Log a custom metric result
|
|
1205
|
-
*
|
|
1206
1036
|
* @param metric - Name of the metric
|
|
1207
1037
|
* @param options - Metric options including index, score, passed, etc.
|
|
1208
|
-
*
|
|
1209
|
-
* If called inside a withTarget() block, the target and index are automatically
|
|
1210
|
-
* inferred from the context and don't need to be specified.
|
|
1211
|
-
*
|
|
1212
1038
|
* @example
|
|
1213
|
-
* ```typescript
|
|
1214
|
-
* // Explicit target (outside withTarget)
|
|
1215
|
-
* evaluation.log('accuracy', { index, score: 0.95, target: 'gpt-4' });
|
|
1216
|
-
*
|
|
1217
|
-
* // Implicit target (inside withTarget)
|
|
1218
|
-
* await evaluation.withTarget('gpt-4', { model: 'openai/gpt-4' }, async () => {
|
|
1219
|
-
* evaluation.log('accuracy', { score: 0.95 }); // target and index auto-inferred
|
|
1220
|
-
* });
|
|
1221
|
-
* ```
|
|
1222
1039
|
*/
|
|
1223
1040
|
log(metric: string, options: LogOptions): void;
|
|
1224
1041
|
/**
|
|
@@ -1226,145 +1043,38 @@ declare class Experiment {
|
|
|
1226
1043
|
*/
|
|
1227
1044
|
private pushEvaluation;
|
|
1228
1045
|
/**
|
|
1229
|
-
* Run a built-in evaluator
|
|
1230
|
-
*
|
|
1231
1046
|
* @param evaluatorSlug - The evaluator identifier (e.g., 'ragas/faithfulness')
|
|
1232
1047
|
* @param options - Evaluator options including data and settings
|
|
1233
|
-
*
|
|
1234
|
-
* If called inside a withTarget() block, the target and index are automatically
|
|
1235
|
-
* inferred from the context and don't need to be specified.
|
|
1236
|
-
*
|
|
1237
1048
|
* @example
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
* await evaluation.withTarget('gpt-4', { model: 'openai/gpt-4' }, async () => {
|
|
1241
|
-
* await evaluation.evaluate('ragas/faithfulness', {
|
|
1242
|
-
* data: { input, output, contexts },
|
|
1243
|
-
* });
|
|
1244
|
-
* });
|
|
1245
|
-
*
|
|
1246
|
-
* // Or explicit index/target
|
|
1247
|
-
* await evaluation.evaluate('ragas/faithfulness', {
|
|
1248
|
-
* index,
|
|
1249
|
-
* data: { input, output, contexts },
|
|
1250
|
-
* target: 'gpt-4',
|
|
1251
|
-
* });
|
|
1252
|
-
* ```
|
|
1253
|
-
*/
|
|
1254
|
-
evaluate(evaluatorSlug: string, options: EvaluateOptions$1): Promise<void>;
|
|
1049
|
+
*/
|
|
1050
|
+
evaluate(evaluatorSlug: string, options: ExperimentEvaluateOptions): Promise<void>;
|
|
1255
1051
|
/**
|
|
1256
1052
|
* Call an evaluator and return its raw result
|
|
1257
1053
|
*/
|
|
1258
1054
|
private callEvaluator;
|
|
1259
1055
|
/**
|
|
1260
|
-
* Compare a row's targets and pick the best one
|
|
1261
|
-
*
|
|
1262
|
-
* Every target that recorded an output for the row is judged together in a
|
|
1263
|
-
* single call, and the winner comes back named with the target name you
|
|
1264
|
-
* registered. Call it once the row's withTarget() calls have all settled,
|
|
1265
|
-
* which under the usual Promise.all is right after the await.
|
|
1266
|
-
*
|
|
1267
|
-
* The verdict grades no single target, so it is recorded against the row.
|
|
1268
|
-
*
|
|
1269
|
-
* The row is named the way log() names it: inside a run() callback it is
|
|
1270
|
-
* inferred from the row being processed, and outside one it is required.
|
|
1271
|
-
*
|
|
1272
|
-
* A row with fewer than two outputs cannot be compared: it is recorded as
|
|
1273
|
-
* skipped, naming the targets that produced nothing, and the run carries on.
|
|
1274
|
-
* A judge that fails or cannot be reached comes back as an `error` verdict
|
|
1275
|
-
* for the same reason, and stays distinct from `inconclusive`, which is the
|
|
1276
|
-
* judge telling you something about your candidates. Naming a target that
|
|
1277
|
-
* produced no output is a different thing again, and throws, because a
|
|
1278
|
-
* two-way verdict read as the three-way one you asked for is worse than a
|
|
1279
|
-
* failure.
|
|
1280
|
-
*
|
|
1281
1056
|
* @param options - How the judge should read the row, and which row when
|
|
1282
|
-
* it cannot be inferred
|
|
1283
1057
|
* @returns The verdict, including the candidates it actually saw
|
|
1284
|
-
*
|
|
1285
1058
|
* @example
|
|
1286
|
-
* ```typescript
|
|
1287
|
-
* await experiment.run(dataset, async ({ item }) => {
|
|
1288
|
-
* await Promise.all([
|
|
1289
|
-
* experiment.withTarget('gpt-5-mini', () => askGpt(item.question)),
|
|
1290
|
-
* experiment.withTarget('claude-sonnet-5', () => askClaude(item.question)),
|
|
1291
|
-
* ]);
|
|
1292
|
-
*
|
|
1293
|
-
* const verdict = await experiment.compare({ input: item.question });
|
|
1294
|
-
* console.log(verdict.winner);
|
|
1295
|
-
* });
|
|
1296
|
-
* ```
|
|
1297
1059
|
*/
|
|
1298
1060
|
compare(options?: ComparisonOptions): Promise<ComparisonVerdict>;
|
|
1299
1061
|
/**
|
|
1300
1062
|
* The row a comparison is about
|
|
1301
|
-
*
|
|
1302
|
-
* Inferred from the row being processed, the same way withTarget() and
|
|
1303
|
-
* log() infer theirs, so a comparison inside a run() callback never repeats
|
|
1304
|
-
* an index the SDK already has. It reads that row from the iteration's own
|
|
1305
|
-
* context, which is what keeps a run of many rows at once from handing one
|
|
1306
|
-
* row's comparison the row a neighbour happens to be on.
|
|
1307
|
-
*
|
|
1308
|
-
* What it deliberately does not do is fall back to a row: judging row 0
|
|
1309
|
-
* because no row was named would hand back a confident verdict about
|
|
1310
|
-
* candidates the caller never asked about.
|
|
1311
1063
|
*/
|
|
1312
1064
|
private resolveComparisonRow;
|
|
1313
1065
|
/**
|
|
1314
1066
|
* Record a comparison verdict against the row
|
|
1315
|
-
*
|
|
1316
|
-
* The verdict the caller is handed is the only input, so the row can never
|
|
1317
|
-
* say one thing while the return value says another.
|
|
1318
|
-
*
|
|
1319
|
-
* Deliberately not routed through log(): a comparison grades no single
|
|
1320
|
-
* target, so it must not pick one up from an ambient withTarget() context,
|
|
1321
|
-
* and it is recorded under the judge's own evaluator id so the results page
|
|
1322
|
-
* can tell it apart from a hand-logged metric.
|
|
1323
1067
|
*/
|
|
1324
1068
|
private recordComparison;
|
|
1325
1069
|
/**
|
|
1326
|
-
* Execute code within a target context with automatic tracing
|
|
1327
|
-
*
|
|
1328
|
-
* Creates a new span for this target execution and sets up context
|
|
1329
|
-
* so that log() calls inside the callback automatically use this target.
|
|
1330
|
-
* Duration and output are captured automatically.
|
|
1331
|
-
*
|
|
1332
|
-
* This creates a dataset entry per target (like Evaluations V3), enabling
|
|
1333
|
-
* proper per-target latency and cost tracking.
|
|
1334
|
-
*
|
|
1070
|
+
* Execute code within a target context with automatic tracing.
|
|
1335
1071
|
* @param targetName - Unique identifier for the target
|
|
1336
|
-
* @param metadata - Optional metadata for comparison (e.g., { model: 'gpt-4' })
|
|
1337
1072
|
* @param callback - Function to execute within the target context
|
|
1338
|
-
* @returns The callback result along with captured metrics
|
|
1339
|
-
*
|
|
1340
|
-
* @example
|
|
1341
|
-
* ```typescript
|
|
1342
|
-
* await evaluation.run(dataset, async ({ item, index }) => {
|
|
1343
|
-
* // Compare GPT-4 and Claude on the same input
|
|
1344
|
-
* const [gpt4Result, claudeResult] = await Promise.all([
|
|
1345
|
-
* evaluation.withTarget('gpt-4', { model: 'openai/gpt-4' }, async () => {
|
|
1346
|
-
* const response = await openai.chat(item.question);
|
|
1347
|
-
* evaluation.log('quality', { score: 0.95 }); // target auto-inferred
|
|
1348
|
-
* return response;
|
|
1349
|
-
* }),
|
|
1350
|
-
* evaluation.withTarget('claude-3', { model: 'anthropic/claude-3' }, async () => {
|
|
1351
|
-
* const response = await anthropic.messages(item.question);
|
|
1352
|
-
* evaluation.log('quality', { score: 0.85 }); // target auto-inferred
|
|
1353
|
-
* return response;
|
|
1354
|
-
* }),
|
|
1355
|
-
* ]);
|
|
1356
|
-
* });
|
|
1357
|
-
* ```
|
|
1358
1073
|
*/
|
|
1359
1074
|
withTarget<R>(targetName: string, metadata: TargetMetadata | null, callback: TargetCallback<R>): Promise<TargetResult<R>>;
|
|
1360
1075
|
withTarget<R>(targetName: string, callback: TargetCallback<R>): Promise<TargetResult<R>>;
|
|
1361
1076
|
/**
|
|
1362
1077
|
* Keep a target's output for the row so compare() can reach it later
|
|
1363
|
-
*
|
|
1364
|
-
* The batch this output also went into is flushed on a timer and cleared, so
|
|
1365
|
-
* a comparison that read its candidates from there would find them missing
|
|
1366
|
-
* whenever the flush landed first. A target that produced nothing is not
|
|
1367
|
-
* captured at all: it has no output to judge.
|
|
1368
1078
|
*/
|
|
1369
1079
|
private captureTargetOutput;
|
|
1370
1080
|
/**
|
|
@@ -1377,27 +1087,19 @@ declare class Experiment {
|
|
|
1377
1087
|
private scheduleSend;
|
|
1378
1088
|
/**
|
|
1379
1089
|
* Print a CI-friendly summary and optionally exit with code 1 on failure.
|
|
1380
|
-
*
|
|
1381
|
-
* Mirrors `ExperimentRunResult.printSummary` for parity — SDK-driven experiments
|
|
1382
|
-
* can now fail CI builds the same way platform experiments do.
|
|
1383
|
-
*
|
|
1384
1090
|
* @param exitOnFailure - If true (default), calls `process.exit(1)` when any evaluation failed.
|
|
1385
|
-
*
|
|
1386
1091
|
* @example
|
|
1387
|
-
* ```typescript
|
|
1388
|
-
* const experiment = await langwatch.experiments.init("ci-quality-check");
|
|
1389
|
-
* await experiment.run(dataset, async ({ item, index }) => {
|
|
1390
|
-
* const response = await myLLM(item.input);
|
|
1391
|
-
* await experiment.evaluate("ragas/faithfulness", { index, data: { input: item.input, output: response } });
|
|
1392
|
-
* });
|
|
1393
|
-
* experiment.printSummary();
|
|
1394
|
-
* ```
|
|
1395
1092
|
*/
|
|
1396
1093
|
printSummary(exitOnFailure?: boolean): void;
|
|
1397
1094
|
/**
|
|
1398
1095
|
* Send current batch to the API
|
|
1399
1096
|
*/
|
|
1400
1097
|
private sendBatch;
|
|
1098
|
+
/**
|
|
1099
|
+
* Posts one log_results request. A request the server refuses as too large is cut in two
|
|
1100
|
+
* and sent again. When a single entry is refused, the error names it and its size.
|
|
1101
|
+
*/
|
|
1102
|
+
private postLogResults;
|
|
1401
1103
|
/**
|
|
1402
1104
|
* Flush all pending data
|
|
1403
1105
|
*/
|
|
@@ -1434,22 +1136,22 @@ type ExperimentRunSummary = {
|
|
|
1434
1136
|
finishedAt?: number;
|
|
1435
1137
|
stoppedAt?: number;
|
|
1436
1138
|
};
|
|
1437
|
-
targets?:
|
|
1139
|
+
targets?: {
|
|
1438
1140
|
targetId: string;
|
|
1439
1141
|
name: string;
|
|
1440
1142
|
passed: number;
|
|
1441
1143
|
failed: number;
|
|
1442
1144
|
avgLatency: number;
|
|
1443
1145
|
totalCost: number;
|
|
1444
|
-
}
|
|
1445
|
-
evaluators?:
|
|
1146
|
+
}[];
|
|
1147
|
+
evaluators?: {
|
|
1446
1148
|
evaluatorId: string;
|
|
1447
1149
|
name: string;
|
|
1448
1150
|
passed: number;
|
|
1449
1151
|
failed: number;
|
|
1450
1152
|
passRate: number;
|
|
1451
1153
|
avgScore?: number;
|
|
1452
|
-
}
|
|
1154
|
+
}[];
|
|
1453
1155
|
totalPassed?: number;
|
|
1454
1156
|
totalFailed?: number;
|
|
1455
1157
|
passRate?: number;
|
|
@@ -1474,16 +1176,14 @@ type RunExperimentOptions = {
|
|
|
1474
1176
|
};
|
|
1475
1177
|
/**
|
|
1476
1178
|
* Inputs that override a platform experiment or workflow run on the server.
|
|
1477
|
-
*
|
|
1478
|
-
* `
|
|
1479
|
-
* both). `parameters` overrides target parameters (e.g. prompt variables) and
|
|
1480
|
-
* `rowIndices` restricts execution to a subset of the configured dataset.
|
|
1179
|
+
* `data`/`datasetId` are mutually exclusive (backend rejects both).
|
|
1180
|
+
* `parameters` overrides target params; `rowIndices` subsets the dataset.
|
|
1481
1181
|
*/
|
|
1482
1182
|
type RunWithResultsOptions = {
|
|
1483
1183
|
/**
|
|
1484
1184
|
* Inline rows to evaluate. Mutually exclusive with `datasetId`.
|
|
1485
1185
|
*/
|
|
1486
|
-
data?:
|
|
1186
|
+
data?: Record<string, unknown>[];
|
|
1487
1187
|
/**
|
|
1488
1188
|
* Id of a saved dataset to evaluate. Mutually exclusive with `data`.
|
|
1489
1189
|
*/
|
|
@@ -1578,10 +1278,6 @@ type ExperimentRunResult = {
|
|
|
1578
1278
|
|
|
1579
1279
|
/**
|
|
1580
1280
|
* ExperimentsFacade - Entry point for the experiments API
|
|
1581
|
-
*
|
|
1582
|
-
* Provides:
|
|
1583
|
-
* - `init()` method to create experiment sessions (SDK-defined experiments)
|
|
1584
|
-
* - `run()` method to execute platform-configured experiments (Experiments Workbench)
|
|
1585
1281
|
*/
|
|
1586
1282
|
|
|
1587
1283
|
type ExperimentsFacadeConfig = {
|
|
@@ -1598,68 +1294,21 @@ declare class ExperimentsFacade {
|
|
|
1598
1294
|
private readonly apiService;
|
|
1599
1295
|
constructor(config: ExperimentsFacadeConfig);
|
|
1600
1296
|
/**
|
|
1601
|
-
* Initialize a new experiment session (SDK-defined)
|
|
1602
|
-
*
|
|
1297
|
+
* Initialize a new experiment session (SDK-defined).
|
|
1603
1298
|
* @param name - Name of the experiment (used as slug)
|
|
1604
1299
|
* @param options - Optional configuration
|
|
1605
|
-
* @returns An initialized Experiment instance
|
|
1606
|
-
*
|
|
1607
|
-
* @example
|
|
1608
|
-
* ```typescript
|
|
1609
|
-
* const experiment = await langwatch.experiments.init('my-experiment');
|
|
1610
|
-
*
|
|
1611
|
-
* await experiment.run(dataset, async ({ item, index }) => {
|
|
1612
|
-
* const response = await myAgent(item.question);
|
|
1613
|
-
* experiment.log('accuracy', { index, score: 0.95 });
|
|
1614
|
-
* });
|
|
1615
|
-
* ```
|
|
1616
1300
|
*/
|
|
1617
1301
|
init(name: string, options?: ExperimentInitOptions): Promise<Experiment>;
|
|
1618
1302
|
/**
|
|
1619
|
-
* Run a platform-configured experiment (Experiments Workbench)
|
|
1620
|
-
*
|
|
1621
|
-
* This runs an experiment that was configured in the LangWatch platform.
|
|
1622
|
-
* The method automatically prints a summary and exits with code 1 on failure
|
|
1623
|
-
* (unless `exitOnFailure: false` is passed).
|
|
1624
|
-
*
|
|
1303
|
+
* Run a platform-configured experiment (Experiments Workbench). Prints a
|
|
1304
|
+
* summary and exits with code 1 on failure, unless `exitOnFailure: false`.
|
|
1625
1305
|
* @param slug - The slug of the experiment (found in the experiment URL)
|
|
1626
|
-
* @param options - Optional configuration
|
|
1627
|
-
* @returns The experiment results including pass rate and summary
|
|
1628
|
-
*
|
|
1629
|
-
* @example
|
|
1630
|
-
* ```typescript
|
|
1631
|
-
* import { LangWatch } from "langwatch";
|
|
1632
|
-
*
|
|
1633
|
-
* const langwatch = new LangWatch();
|
|
1634
|
-
*
|
|
1635
|
-
* const result = await langwatch.experiments.run("my-experiment-slug");
|
|
1636
|
-
* result.printSummary();
|
|
1637
|
-
* ```
|
|
1638
1306
|
*/
|
|
1639
1307
|
run(slug: string, options?: RunExperimentOptions): Promise<ExperimentRunResult>;
|
|
1640
1308
|
/**
|
|
1641
1309
|
* Run a platform experiment and return per-row structured results.
|
|
1642
|
-
*
|
|
1643
|
-
* Starts the run through the unified evaluations-v3 backend (optionally
|
|
1644
|
-
* overriding the configured inputs via `data` / `datasetId` / `parameters` /
|
|
1645
|
-
* `rowIndices`), polls to completion, fetches the per-row results, and maps
|
|
1646
|
-
* them to the same row structure as the python SDK's results DataFrame.
|
|
1647
|
-
*
|
|
1648
1310
|
* @param slug - The slug of the experiment (found in the experiment URL)
|
|
1649
1311
|
* @param options - Optional inputs and polling configuration
|
|
1650
|
-
* @returns The run id, results URL, status, summary, and per-row results
|
|
1651
|
-
*
|
|
1652
|
-
* @example
|
|
1653
|
-
* ```typescript
|
|
1654
|
-
* const langwatch = new LangWatch();
|
|
1655
|
-
* const { rows, runUrl } = await langwatch.experiments.runWithResults(
|
|
1656
|
-
* "my-experiment-slug",
|
|
1657
|
-
* { data: [{ question: "What is 2 + 2?" }] },
|
|
1658
|
-
* );
|
|
1659
|
-
* for (const row of rows) {
|
|
1660
|
-
* console.log(row.output, row.evaluations);
|
|
1661
|
-
* }
|
|
1662
|
-
* ```
|
|
1663
1312
|
*/
|
|
1664
1313
|
runWithResults(slug: string, options?: RunWithResultsOptions): Promise<ExperimentRunWithResults>;
|
|
1665
1314
|
/**
|
|
@@ -1717,11 +1366,9 @@ declare class TargetMetadataConflictError extends ExperimentError {
|
|
|
1717
1366
|
constructor(targetName: string, existingMetadata: Record<string, unknown>, newMetadata: Record<string, unknown>);
|
|
1718
1367
|
}
|
|
1719
1368
|
/**
|
|
1720
|
-
* Thrown when a comparison cannot produce a verdict the caller asked for
|
|
1721
|
-
*
|
|
1722
|
-
*
|
|
1723
|
-
* reserved for a mismatch between what the caller named and what the run
|
|
1724
|
-
* actually recorded.
|
|
1369
|
+
* Thrown when a comparison cannot produce a verdict the caller asked for.
|
|
1370
|
+
* A too-thin-to-judge row is skipped instead -- this is reserved for a
|
|
1371
|
+
* mismatch between what the caller named and what the run recorded.
|
|
1725
1372
|
*/
|
|
1726
1373
|
declare class ComparisonError extends ExperimentError {
|
|
1727
1374
|
readonly missingTargets: string[];
|
|
@@ -1736,12 +1383,7 @@ declare class EvaluatorError extends ExperimentError {
|
|
|
1736
1383
|
constructor(evaluatorSlug: string, message: string, cause?: Error | undefined);
|
|
1737
1384
|
}
|
|
1738
1385
|
|
|
1739
|
-
/**
|
|
1740
|
-
* Types for the Evaluations API (Online Evaluations / Guardrails)
|
|
1741
|
-
*
|
|
1742
|
-
* These types define the structure for running evaluators and guardrails
|
|
1743
|
-
* in real-time against LLM inputs/outputs.
|
|
1744
|
-
*/
|
|
1386
|
+
/** Types for the Evaluations API: running evaluators/guardrails in real time against LLM I/O. */
|
|
1745
1387
|
/**
|
|
1746
1388
|
* Status of an evaluation result
|
|
1747
1389
|
*/
|
|
@@ -1785,26 +1427,9 @@ type EvaluateOptions = {
|
|
|
1785
1427
|
};
|
|
1786
1428
|
|
|
1787
1429
|
/**
|
|
1788
|
-
* EvaluationsFacade - Entry point for the Evaluations API (Online Evaluations /
|
|
1789
|
-
*
|
|
1790
|
-
* Provides an API for running evaluators and guardrails in real-time against LLM inputs/outputs.
|
|
1791
|
-
*
|
|
1430
|
+
* EvaluationsFacade - Entry point for the Evaluations API (Online Evaluations /
|
|
1431
|
+
* Guardrails)
|
|
1792
1432
|
* @example
|
|
1793
|
-
* ```typescript
|
|
1794
|
-
* const langwatch = new LangWatch({ apiKey: "your-api-key" });
|
|
1795
|
-
*
|
|
1796
|
-
* // Run a guardrail
|
|
1797
|
-
* const guardrail = await langwatch.evaluations.evaluate("presidio/pii_detection", {
|
|
1798
|
-
* data: { input: userInput, output: generatedResponse },
|
|
1799
|
-
* name: "PII Detection",
|
|
1800
|
-
* asGuardrail: true,
|
|
1801
|
-
* settings: {},
|
|
1802
|
-
* });
|
|
1803
|
-
*
|
|
1804
|
-
* if (!guardrail.passed) {
|
|
1805
|
-
* return "I'm sorry, I can't do that.";
|
|
1806
|
-
* }
|
|
1807
|
-
* ```
|
|
1808
1433
|
*/
|
|
1809
1434
|
|
|
1810
1435
|
type EvaluationsFacadeConfig = {
|
|
@@ -1816,42 +1441,9 @@ declare class EvaluationsFacade {
|
|
|
1816
1441
|
#private;
|
|
1817
1442
|
constructor(config: EvaluationsFacadeConfig);
|
|
1818
1443
|
/**
|
|
1819
|
-
* Run an evaluator or guardrail against provided data
|
|
1820
|
-
*
|
|
1821
|
-
* Creates an OpenTelemetry span attached to the current trace context,
|
|
1822
|
-
* calls the LangWatch evaluation API, and returns the result.
|
|
1823
|
-
*
|
|
1444
|
+
* Run an evaluator or guardrail against provided data.
|
|
1824
1445
|
* @param slug - The evaluator slug (e.g., "presidio/pii_detection", "langevals/llm_boolean")
|
|
1825
1446
|
* @param options - Evaluation options including data, name, settings, and asGuardrail flag
|
|
1826
|
-
* @returns The evaluation result with status, passed, score, details, label, and cost
|
|
1827
|
-
*
|
|
1828
|
-
* @example
|
|
1829
|
-
* ```typescript
|
|
1830
|
-
* // Run as a guardrail (synchronous evaluation that can block responses)
|
|
1831
|
-
* const guardrail = await langwatch.evaluations.evaluate("presidio/pii_detection", {
|
|
1832
|
-
* data: { input: userInput, output: generatedResponse },
|
|
1833
|
-
* name: "PII Detection Guardrail",
|
|
1834
|
-
* asGuardrail: true,
|
|
1835
|
-
* });
|
|
1836
|
-
*
|
|
1837
|
-
* if (!guardrail.passed) {
|
|
1838
|
-
* console.log("PII detected:", guardrail.details);
|
|
1839
|
-
* return "Sorry, I cannot process that request.";
|
|
1840
|
-
* }
|
|
1841
|
-
* ```
|
|
1842
|
-
*
|
|
1843
|
-
* @example
|
|
1844
|
-
* ```typescript
|
|
1845
|
-
* // Run as an online evaluation (async scoring for monitoring)
|
|
1846
|
-
* const result = await langwatch.evaluations.evaluate("langevals/llm_boolean", {
|
|
1847
|
-
* data: { input: question, output: response },
|
|
1848
|
-
* name: "Quality Check",
|
|
1849
|
-
* settings: { prompt: "Check if the response answers the question." },
|
|
1850
|
-
* });
|
|
1851
|
-
*
|
|
1852
|
-
* console.log("Score:", result.score);
|
|
1853
|
-
* console.log("Details:", result.details);
|
|
1854
|
-
* ```
|
|
1855
1447
|
*/
|
|
1856
1448
|
evaluate: (slug: string, options: EvaluateOptions) => Promise<EvaluationResult>;
|
|
1857
1449
|
}
|
|
@@ -1888,14 +1480,14 @@ declare class EvaluationsApiError extends EvaluationError {
|
|
|
1888
1480
|
constructor(message: string, statusCode: number);
|
|
1889
1481
|
}
|
|
1890
1482
|
|
|
1891
|
-
type EvaluatorResponse = NonNullable<paths["/api/evaluators"]["get"]["responses"]["200"]["content"]["application/json"]>[number] & {
|
|
1483
|
+
type EvaluatorResponse = NonNullable<paths["/api/v1/evaluators"]["get"]["responses"]["200"]["content"]["application/json"]>[number] & {
|
|
1892
1484
|
/** URL to view this evaluator on the LangWatch platform */
|
|
1893
1485
|
platformUrl?: string;
|
|
1894
1486
|
};
|
|
1895
1487
|
type EvaluatorField = EvaluatorResponse["fields"][number];
|
|
1896
|
-
type CreateEvaluatorBody = NonNullable<paths["/api/evaluators"]["post"]["requestBody"]>["content"]["application/json"];
|
|
1897
|
-
type UpdateEvaluatorBody = NonNullable<paths["/api/evaluators/{id}"]["put"]["requestBody"]>["content"]["application/json"];
|
|
1898
|
-
type DeleteEvaluatorResponse = paths["/api/evaluators/{id}"]["delete"]["responses"]["200"]["content"]["application/json"];
|
|
1488
|
+
type CreateEvaluatorBody = NonNullable<paths["/api/v1/evaluators"]["post"]["requestBody"]>["content"]["application/json"];
|
|
1489
|
+
type UpdateEvaluatorBody = NonNullable<paths["/api/v1/evaluators/{id}"]["put"]["requestBody"]>["content"]["application/json"];
|
|
1490
|
+
type DeleteEvaluatorResponse = paths["/api/v1/evaluators/{id}"]["delete"]["responses"]["200"]["content"]["application/json"];
|
|
1899
1491
|
|
|
1900
1492
|
/**
|
|
1901
1493
|
* Service for retrieving evaluator resources via the LangWatch API.
|
|
@@ -1934,15 +1526,15 @@ declare class EvaluatorsApiError extends Error {
|
|
|
1934
1526
|
constructor(message: string, operation: string, originalError?: unknown | undefined);
|
|
1935
1527
|
}
|
|
1936
1528
|
|
|
1937
|
-
type ScenarioResponse = NonNullable<paths["/api/scenarios"]["get"]["responses"]["200"]["content"]["application/json"]>[number] & {
|
|
1529
|
+
type ScenarioResponse = NonNullable<paths["/api/v1/scenarios"]["get"]["responses"]["200"]["content"]["application/json"]>[number] & {
|
|
1938
1530
|
/** URL to view this scenario on the LangWatch platform */
|
|
1939
1531
|
platformUrl?: string;
|
|
1940
1532
|
};
|
|
1941
|
-
type CreateScenarioBody = NonNullable<paths["/api/scenarios"]["post"]["requestBody"]>["content"]["application/json"];
|
|
1942
|
-
type UpdateScenarioBody = NonNullable<paths["/api/scenarios/{id}"]["put"]["requestBody"]>["content"]["application/json"];
|
|
1943
|
-
type DeleteScenarioResponse = paths["/api/scenarios/{id}"]["delete"]["responses"]["200"]["content"]["application/json"];
|
|
1944
|
-
type ScenarioVersionListResponse = paths["/api/scenarios/{id}/versions"]["get"]["responses"]["200"]["content"]["application/json"];
|
|
1945
|
-
type ScenarioVersionDetail = paths["/api/scenarios/{id}/versions/{version}"]["get"]["responses"]["200"]["content"]["application/json"];
|
|
1533
|
+
type CreateScenarioBody = NonNullable<paths["/api/v1/scenarios"]["post"]["requestBody"]>["content"]["application/json"];
|
|
1534
|
+
type UpdateScenarioBody = NonNullable<paths["/api/v1/scenarios/{id}"]["put"]["requestBody"]>["content"]["application/json"];
|
|
1535
|
+
type DeleteScenarioResponse = paths["/api/v1/scenarios/{id}"]["delete"]["responses"]["200"]["content"]["application/json"];
|
|
1536
|
+
type ScenarioVersionListResponse = paths["/api/v1/scenarios/{id}/versions"]["get"]["responses"]["200"]["content"]["application/json"];
|
|
1537
|
+
type ScenarioVersionDetail = paths["/api/v1/scenarios/{id}/versions/{version}"]["get"]["responses"]["200"]["content"]["application/json"];
|
|
1946
1538
|
|
|
1947
1539
|
declare class ScenariosApiService {
|
|
1948
1540
|
private readonly apiClient;
|
|
@@ -1962,19 +1554,19 @@ declare class ScenariosApiService {
|
|
|
1962
1554
|
delete(id: string): Promise<DeleteScenarioResponse>;
|
|
1963
1555
|
}
|
|
1964
1556
|
|
|
1965
|
-
type SuiteResponse = NonNullable<paths["/api/suites"]["get"]["responses"]["200"]["content"]["application/json"]>[number] & {
|
|
1557
|
+
type SuiteResponse = NonNullable<paths["/api/v1/suites"]["get"]["responses"]["200"]["content"]["application/json"]>[number] & {
|
|
1966
1558
|
/** URL to view this suite on the LangWatch platform */
|
|
1967
1559
|
platformUrl?: string;
|
|
1968
1560
|
};
|
|
1969
|
-
type CreateSuiteBody = NonNullable<paths["/api/suites"]["post"]["requestBody"]>["content"]["application/json"];
|
|
1970
|
-
type UpdateSuiteBody = NonNullable<paths["/api/suites/{id}"]["patch"]["requestBody"]>["content"]["application/json"];
|
|
1971
|
-
type SuiteRunResult = paths["/api/suites/{id}/run"]["post"]["responses"]["200"]["content"]["application/json"];
|
|
1972
|
-
/** Options for `POST /api/suites/{id}/run`. */
|
|
1561
|
+
type CreateSuiteBody = NonNullable<paths["/api/v1/suites"]["post"]["requestBody"]>["content"]["application/json"];
|
|
1562
|
+
type UpdateSuiteBody = NonNullable<paths["/api/v1/suites/{id}"]["patch"]["requestBody"]>["content"]["application/json"];
|
|
1563
|
+
type SuiteRunResult = paths["/api/v1/suites/{id}/run"]["post"]["responses"]["200"]["content"]["application/json"];
|
|
1564
|
+
/** Options for `POST /api/v1/suites/{id}/run`. */
|
|
1973
1565
|
interface SuiteRunOptions {
|
|
1974
1566
|
/**
|
|
1975
|
-
*
|
|
1976
|
-
*
|
|
1977
|
-
*
|
|
1567
|
+
* Makes the run safe to retry: the same key on a second call joins the batch
|
|
1568
|
+
* the first started. Omitted, no key is sent and every call schedules its own
|
|
1569
|
+
* run. Pin one per logical run, never per attempt.
|
|
1978
1570
|
*/
|
|
1979
1571
|
idempotencyKey?: string;
|
|
1980
1572
|
/**
|
|
@@ -1993,7 +1585,7 @@ interface SuiteRunOptions {
|
|
|
1993
1585
|
/** Which kind of suite `getAll` returns. Defaults to run plans. */
|
|
1994
1586
|
type SuiteKind = "custom" | "folder";
|
|
1995
1587
|
/**
|
|
1996
|
-
* @deprecated Use runPlans and testSuites; /api/suites is a frozen alias.
|
|
1588
|
+
* @deprecated Use runPlans and testSuites; /api/v1/suites is a frozen alias.
|
|
1997
1589
|
*/
|
|
1998
1590
|
declare class SuitesApiService {
|
|
1999
1591
|
private readonly apiClient;
|
|
@@ -2028,12 +1620,6 @@ type RunPlanRunResult = paths["/api/v1/run-plans/run"]["post"]["responses"]["200
|
|
|
2028
1620
|
type RunPlanRerunBody = NonNullable<paths["/api/v1/run-plans/{id}/run"]["post"]["requestBody"]>["content"]["application/json"];
|
|
2029
1621
|
/**
|
|
2030
1622
|
* Typed client for the run plan family (`/api/v1/run-plans`).
|
|
2031
|
-
*
|
|
2032
|
-
* A run plan is identified by its NAME. Posting a configuration under a name
|
|
2033
|
-
* already in use replaces that plan's configuration and joins its history;
|
|
2034
|
-
* posting under a new name creates the plan; posting no name lets the platform
|
|
2035
|
-
* derive one from what the run covers and what it runs against.
|
|
2036
|
-
*
|
|
2037
1623
|
* @see specs/typescript-sdk/run-plans-and-test-suites.feature
|
|
2038
1624
|
*/
|
|
2039
1625
|
declare class RunPlansApiService {
|
|
@@ -2047,9 +1633,6 @@ declare class RunPlansApiService {
|
|
|
2047
1633
|
get(id: string): Promise<RunPlan>;
|
|
2048
1634
|
/**
|
|
2049
1635
|
* Runs a configuration under a name.
|
|
2050
|
-
*
|
|
2051
|
-
* A note of only spaces is no note: sending an empty string would store a
|
|
2052
|
-
* value every reader then has to filter out.
|
|
2053
1636
|
*/
|
|
2054
1637
|
run(body: RunPlanRunBody): Promise<RunPlanRunResult>;
|
|
2055
1638
|
/** Runs a plan again with the configuration it already holds. */
|
|
@@ -2073,16 +1656,10 @@ type InstantEvalJudgment = InstantEvalResultsPage["judgments"][number];
|
|
|
2073
1656
|
/** A few of a run's rows, with the judged text beside the verdict. */
|
|
2074
1657
|
type InstantEvalSample = paths["/api/v1/instant-evals/{id}/sample"]["get"]["responses"]["200"]["content"]["application/json"];
|
|
2075
1658
|
/**
|
|
2076
|
-
* Typed client for
|
|
2077
|
-
*
|
|
2078
|
-
*
|
|
2079
|
-
*
|
|
2080
|
-
* working run once it projects `TraceId` and at least one eval function
|
|
2081
|
-
* column. Starting one answers the queued run, and its progress is polled.
|
|
2082
|
-
*
|
|
2083
|
-
* The project comes from the credential, so no method takes a project id.
|
|
2084
|
-
*
|
|
2085
|
-
* @see specs/instant-evals/instant-eval-api.feature
|
|
1659
|
+
* Typed client for Instant Evals (`/api/v1/instant-evals`): a run judges one LangWatchQL statement
|
|
1660
|
+
* that projects `TraceId` and an eval column. Progress is polled; the project comes from the
|
|
1661
|
+
* credential.
|
|
1662
|
+
* @see modules/instant-eval/specs/instant-eval-api.feature
|
|
2086
1663
|
*/
|
|
2087
1664
|
declare class InstantEvalsApiService {
|
|
2088
1665
|
private readonly apiClient;
|
|
@@ -2108,10 +1685,8 @@ declare class InstantEvalsApiService {
|
|
|
2108
1685
|
/** Asks a run to stop. It stops before its next page. */
|
|
2109
1686
|
cancel(id: string): Promise<InstantEvalRun>;
|
|
2110
1687
|
/**
|
|
2111
|
-
* One page of a run's judgements.
|
|
2112
|
-
*
|
|
2113
|
-
* Pass the `nextCursor` a page answers with to read the page after it. The
|
|
2114
|
-
* last page carries none.
|
|
1688
|
+
* One page of a run's judgements. Pass the `nextCursor` a page answers with to read the page
|
|
1689
|
+
* after it. The last page carries none.
|
|
2115
1690
|
*/
|
|
2116
1691
|
results(id: string, options?: {
|
|
2117
1692
|
questionId?: string;
|
|
@@ -2145,11 +1720,6 @@ type RunTestSuiteBody = NonNullable<paths["/api/v1/test-suites/{id}/run"]["post"
|
|
|
2145
1720
|
type TestSuiteRunResult = RunPlanRunResult;
|
|
2146
1721
|
/**
|
|
2147
1722
|
* Typed client for the test suite family (`/api/v1/test-suites`).
|
|
2148
|
-
*
|
|
2149
|
-
* A test suite is a group of scenarios: a name, and the scenarios filed in it.
|
|
2150
|
-
* It holds no targets and no configuration, so running one sends its targets with
|
|
2151
|
-
* the request and the platform files the run under a run plan.
|
|
2152
|
-
*
|
|
2153
1723
|
* @see specs/typescript-sdk/run-plans-and-test-suites.feature
|
|
2154
1724
|
*/
|
|
2155
1725
|
declare class TestSuitesApiService {
|
|
@@ -2182,8 +1752,8 @@ declare class TestSuitesApiService {
|
|
|
2182
1752
|
run(id: string, body: RunTestSuiteBody): Promise<TestSuiteRunResult>;
|
|
2183
1753
|
}
|
|
2184
1754
|
|
|
2185
|
-
type WorkflowResponse = NonNullable<paths["/api/workflows"]["get"]["responses"]["200"]["content"]["application/json"]>[number];
|
|
2186
|
-
type WorkflowDeleteResponse = paths["/api/workflows/{id}"]["delete"]["responses"]["200"]["content"]["application/json"];
|
|
1755
|
+
type WorkflowResponse = NonNullable<paths["/api/v1/workflows"]["get"]["responses"]["200"]["content"]["application/json"]>[number];
|
|
1756
|
+
type WorkflowDeleteResponse = paths["/api/v1/workflows/{id}"]["delete"]["responses"]["200"]["content"]["application/json"];
|
|
2187
1757
|
declare class WorkflowsApiService {
|
|
2188
1758
|
private readonly apiClient;
|
|
2189
1759
|
private readonly experimentsApiService;
|
|
@@ -2198,25 +1768,8 @@ declare class WorkflowsApiService {
|
|
|
2198
1768
|
delete(id: string): Promise<WorkflowDeleteResponse>;
|
|
2199
1769
|
/**
|
|
2200
1770
|
* Run a studio workflow evaluation and return per-row structured results.
|
|
2201
|
-
*
|
|
2202
|
-
* Starts the evaluation through the unified evaluations-v3 backend
|
|
2203
|
-
* (`POST /api/workflows/{workflowId}/evaluate`), polls to completion, fetches
|
|
2204
|
-
* the per-row results, and maps them to the same row structure as the python
|
|
2205
|
-
* SDK's results DataFrame.
|
|
2206
|
-
*
|
|
2207
1771
|
* @param workflowId - The studio workflow id
|
|
2208
|
-
* @param options - Optional inputs
|
|
2209
|
-
* configuration. `data` and `datasetId` are mutually
|
|
2210
|
-
* exclusive.
|
|
2211
|
-
* @returns The run id, results URL, status, summary, and per-row results
|
|
2212
|
-
*
|
|
2213
|
-
* @example
|
|
2214
|
-
* ```typescript
|
|
2215
|
-
* const langwatch = new LangWatch();
|
|
2216
|
-
* const { rows, runUrl } = await langwatch.workflows.run("workflow_123", {
|
|
2217
|
-
* data: [{ question: "What is 2 + 2?" }],
|
|
2218
|
-
* });
|
|
2219
|
-
* ```
|
|
1772
|
+
* @param options - Optional inputs and polling configuration
|
|
2220
1773
|
*/
|
|
2221
1774
|
run(workflowId: string, options?: RunWithResultsOptions & {
|
|
2222
1775
|
versionId?: string;
|
|
@@ -2316,16 +1869,19 @@ declare class AgentsApiService {
|
|
|
2316
1869
|
*/
|
|
2317
1870
|
call(id: string, body: AgentCallBody): Promise<AgentCallResponse>;
|
|
2318
1871
|
/**
|
|
2319
|
-
* Runs one scripted scenario against an agent: the user sends "ping", the
|
|
2320
|
-
*
|
|
2321
|
-
*
|
|
2322
|
-
* ids to follow.
|
|
1872
|
+
* Runs one scripted scenario against an agent: the user sends "ping", the agent answers,
|
|
1873
|
+
* and the run succeeds when the answer arrives. The project gains no scenario, run plan or
|
|
1874
|
+
* test suite, and the answer carries the run ids to follow.
|
|
2323
1875
|
*/
|
|
2324
1876
|
test(id: string): Promise<AgentTestRunResponse>;
|
|
2325
1877
|
}
|
|
2326
1878
|
|
|
2327
1879
|
type AnnotationResponse = components["schemas"]["Annotation"];
|
|
2328
|
-
type CreateAnnotationBody = NonNullable<paths["/api/annotations/trace/{id}"]["post"]["requestBody"]>["content"]["application/json"];
|
|
1880
|
+
type CreateAnnotationBody = NonNullable<paths["/api/v1/annotations/trace/{id}"]["post"]["requestBody"]>["content"]["application/json"];
|
|
1881
|
+
type DeleteAnnotationResponse = {
|
|
1882
|
+
status?: string;
|
|
1883
|
+
message?: string;
|
|
1884
|
+
};
|
|
2329
1885
|
declare class AnnotationsApiService {
|
|
2330
1886
|
private readonly apiClient;
|
|
2331
1887
|
constructor(config?: Pick<InternalConfig, "langwatchApiClient">);
|
|
@@ -2334,13 +1890,76 @@ declare class AnnotationsApiService {
|
|
|
2334
1890
|
get(id: string): Promise<AnnotationResponse>;
|
|
2335
1891
|
getByTrace(traceId: string): Promise<AnnotationResponse[]>;
|
|
2336
1892
|
create(traceId: string, params: CreateAnnotationBody): Promise<AnnotationResponse>;
|
|
2337
|
-
delete(id: string): Promise<
|
|
2338
|
-
|
|
2339
|
-
|
|
1893
|
+
delete(id: string): Promise<DeleteAnnotationResponse>;
|
|
1894
|
+
}
|
|
1895
|
+
|
|
1896
|
+
type Json<T> = T extends {
|
|
1897
|
+
content: {
|
|
1898
|
+
"application/json": infer Body;
|
|
1899
|
+
};
|
|
1900
|
+
} ? Body : never;
|
|
1901
|
+
/** A dashboard as `/api/v1/dashboards/{dashboardId}` answers it. */
|
|
1902
|
+
type Dashboard = Json<paths["/api/v1/dashboards/{dashboardId}"]["get"]["responses"]["200"]>;
|
|
1903
|
+
/** One row of the dashboards list, with its widget count. */
|
|
1904
|
+
type DashboardListItem = Json<paths["/api/v1/dashboards"]["get"]["responses"]["200"]>["data"][number];
|
|
1905
|
+
/** A widget on a dashboard, as the dashboard's widget routes answer it. */
|
|
1906
|
+
type DashboardWidget = Json<paths["/api/v1/dashboards/{dashboardId}/widgets/{widgetId}"]["get"]["responses"]["200"]>;
|
|
1907
|
+
/** What creating a widget on a dashboard submits. */
|
|
1908
|
+
type CreateDashboardWidgetInput = NonNullable<paths["/api/v1/dashboards/{dashboardId}/widgets"]["post"]["requestBody"]>["content"]["application/json"];
|
|
1909
|
+
/** What updating a widget on a dashboard submits; a field left out keeps its value. */
|
|
1910
|
+
type UpdateDashboardWidgetInput = NonNullable<paths["/api/v1/dashboards/{dashboardId}/widgets/{widgetId}"]["patch"]["requestBody"]>["content"]["application/json"];
|
|
1911
|
+
/**
|
|
1912
|
+
* Typed client for `/api/v1/dashboards`: the key's project's dashboards and the widgets on them.
|
|
1913
|
+
* The project comes from the API key; while Dashboards is off the routes answer 404.
|
|
1914
|
+
*/
|
|
1915
|
+
declare class DashboardsApiService {
|
|
1916
|
+
private readonly apiClient;
|
|
1917
|
+
constructor(config?: Pick<InternalConfig, "langwatchApiClient">);
|
|
1918
|
+
private handleApiError;
|
|
1919
|
+
list(): Promise<{
|
|
1920
|
+
data: DashboardListItem[];
|
|
1921
|
+
}>;
|
|
1922
|
+
get(dashboardId: string): Promise<Dashboard>;
|
|
1923
|
+
create({ name }: {
|
|
1924
|
+
name: string;
|
|
1925
|
+
}): Promise<Dashboard>;
|
|
1926
|
+
/** `description: null` clears it; a field left out keeps its value. */
|
|
1927
|
+
update({ dashboardId, name, description, }: {
|
|
1928
|
+
dashboardId: string;
|
|
1929
|
+
name?: string;
|
|
1930
|
+
description?: string | null;
|
|
1931
|
+
}): Promise<Dashboard>;
|
|
1932
|
+
/** Deletes the dashboard with the widgets on it; answers its id and name. */
|
|
1933
|
+
delete(dashboardId: string): Promise<{
|
|
1934
|
+
id: string;
|
|
1935
|
+
name: string;
|
|
1936
|
+
}>;
|
|
1937
|
+
listWidgets(dashboardId: string): Promise<{
|
|
1938
|
+
data: DashboardWidget[];
|
|
2340
1939
|
}>;
|
|
1940
|
+
/** Creates a widget placed on this dashboard. */
|
|
1941
|
+
createWidget({ dashboardId, widget, }: {
|
|
1942
|
+
dashboardId: string;
|
|
1943
|
+
widget: CreateDashboardWidgetInput;
|
|
1944
|
+
}): Promise<DashboardWidget>;
|
|
1945
|
+
getWidget({ dashboardId, widgetId, }: {
|
|
1946
|
+
dashboardId: string;
|
|
1947
|
+
widgetId: string;
|
|
1948
|
+
}): Promise<DashboardWidget>;
|
|
1949
|
+
updateWidget({ dashboardId, widgetId, changes, }: {
|
|
1950
|
+
dashboardId: string;
|
|
1951
|
+
widgetId: string;
|
|
1952
|
+
changes: UpdateDashboardWidgetInput;
|
|
1953
|
+
}): Promise<DashboardWidget>;
|
|
1954
|
+
/** The route answers `204` with no body. */
|
|
1955
|
+
deleteWidget({ dashboardId, widgetId, }: {
|
|
1956
|
+
dashboardId: string;
|
|
1957
|
+
widgetId: string;
|
|
1958
|
+
}): Promise<void>;
|
|
2341
1959
|
}
|
|
2342
1960
|
|
|
2343
|
-
|
|
1961
|
+
/** One Analytics Report in the list, with how many graphs it holds. */
|
|
1962
|
+
interface AnalyticsReportSummary {
|
|
2344
1963
|
id: string;
|
|
2345
1964
|
name: string;
|
|
2346
1965
|
order: number;
|
|
@@ -2349,7 +1968,8 @@ interface DashboardSummary {
|
|
|
2349
1968
|
updatedAt: string;
|
|
2350
1969
|
platformUrl?: string;
|
|
2351
1970
|
}
|
|
2352
|
-
|
|
1971
|
+
/** One Analytics Report with its graphs. */
|
|
1972
|
+
interface AnalyticsReportDetail {
|
|
2353
1973
|
id: string;
|
|
2354
1974
|
name: string;
|
|
2355
1975
|
order: number;
|
|
@@ -2358,28 +1978,32 @@ interface DashboardDetail {
|
|
|
2358
1978
|
updatedAt: string;
|
|
2359
1979
|
platformUrl?: string;
|
|
2360
1980
|
}
|
|
2361
|
-
|
|
1981
|
+
/**
|
|
1982
|
+
* Typed client for the Analytics Reports at `/api/v1/analytics/reports`, deprecated by the
|
|
1983
|
+
* platform in favour of the Dashboards API (`DashboardsApiService`, `/api/v1/dashboards`).
|
|
1984
|
+
*/
|
|
1985
|
+
declare class AnalyticsReportsApiService {
|
|
2362
1986
|
private readonly apiClient;
|
|
2363
1987
|
constructor(config?: Pick<InternalConfig, "langwatchApiClient">);
|
|
2364
1988
|
private handleApiError;
|
|
2365
1989
|
list(): Promise<{
|
|
2366
|
-
data:
|
|
1990
|
+
data: AnalyticsReportSummary[];
|
|
2367
1991
|
}>;
|
|
2368
|
-
get(id: string): Promise<
|
|
1992
|
+
get(id: string): Promise<AnalyticsReportDetail>;
|
|
2369
1993
|
create(params: {
|
|
2370
1994
|
name: string;
|
|
2371
|
-
}): Promise<
|
|
1995
|
+
}): Promise<AnalyticsReportDetail>;
|
|
2372
1996
|
rename(id: string, params: {
|
|
2373
1997
|
name: string;
|
|
2374
|
-
}): Promise<
|
|
1998
|
+
}): Promise<AnalyticsReportDetail>;
|
|
2375
1999
|
delete(id: string): Promise<{
|
|
2376
2000
|
id: string;
|
|
2377
2001
|
name: string;
|
|
2378
2002
|
}>;
|
|
2379
2003
|
}
|
|
2380
2004
|
|
|
2381
|
-
type ModelProvidersListResponse = paths["/api/model-providers"]["get"]["responses"]["200"]["content"]["application/json"];
|
|
2382
|
-
type UpdateModelProviderBody = NonNullable<paths["/api/model-providers/{provider}"]["put"]["requestBody"]>["content"]["application/json"];
|
|
2005
|
+
type ModelProvidersListResponse = paths["/api/v1/model-providers"]["get"]["responses"]["200"]["content"]["application/json"];
|
|
2006
|
+
type UpdateModelProviderBody = NonNullable<paths["/api/v1/model-providers/{provider}"]["put"]["requestBody"]>["content"]["application/json"];
|
|
2383
2007
|
declare class ModelProvidersApiService {
|
|
2384
2008
|
private readonly apiClient;
|
|
2385
2009
|
constructor(config?: Pick<InternalConfig, "langwatchApiClient">);
|
|
@@ -2388,8 +2012,8 @@ declare class ModelProvidersApiService {
|
|
|
2388
2012
|
set(provider: string, params: UpdateModelProviderBody): Promise<ModelProvidersListResponse>;
|
|
2389
2013
|
}
|
|
2390
2014
|
|
|
2391
|
-
type AnalyticsTimeseriesBody = NonNullable<paths["/api/analytics/timeseries"]["post"]["requestBody"]>["content"]["application/json"];
|
|
2392
|
-
type AnalyticsTimeseriesResponse = paths["/api/analytics/timeseries"]["post"]["responses"]["200"]["content"]["application/json"];
|
|
2015
|
+
type AnalyticsTimeseriesBody = NonNullable<paths["/api/v1/analytics/timeseries"]["post"]["requestBody"]>["content"]["application/json"];
|
|
2016
|
+
type AnalyticsTimeseriesResponse = paths["/api/v1/analytics/timeseries"]["post"]["responses"]["200"]["content"]["application/json"];
|
|
2393
2017
|
declare class AnalyticsApiService {
|
|
2394
2018
|
private readonly apiClient;
|
|
2395
2019
|
constructor(config?: Pick<InternalConfig, "langwatchApiClient">);
|
|
@@ -2402,42 +2026,18 @@ type QueryRunResult = paths["/api/v1/query"]["post"]["responses"]["200"]["conten
|
|
|
2402
2026
|
/** The queryable dataset/column catalog `GET /api/v1/query/schema` answers with. */
|
|
2403
2027
|
type QuerySchemaResult = paths["/api/v1/query/schema"]["get"]["responses"]["200"]["content"]["application/json"];
|
|
2404
2028
|
/**
|
|
2405
|
-
* Both query languages
|
|
2406
|
-
*
|
|
2407
|
-
* A superset of {@link QuerySchemaResult} in one direction only: it embeds the
|
|
2408
|
-
* schema and adds the trace filter language, worked examples and the decision
|
|
2409
|
-
* table. Nothing here is tenant data — the values a field holds come from
|
|
2410
|
-
* `GET /api/traces/facets`.
|
|
2029
|
+
* Both query languages as `GET /api/v1/query/reference` describes them: {@link QuerySchemaResult}
|
|
2030
|
+
* plus the filter language, examples and decision table. No tenant data; values come from facets.
|
|
2411
2031
|
*/
|
|
2412
2032
|
type QueryReferenceResult = paths["/api/v1/query/reference"]["get"]["responses"]["200"]["content"]["application/json"];
|
|
2413
2033
|
/**
|
|
2414
2034
|
* The body a query request sends.
|
|
2415
|
-
*
|
|
2416
|
-
* Derived from the generated request body so a contract change to what the
|
|
2417
|
-
* endpoint accepts breaks this at compile time rather than drifting silently.
|
|
2418
2035
|
*/
|
|
2419
2036
|
type QueryRunParams = NonNullable<paths["/api/v1/query"]["post"]["requestBody"]>["content"]["application/json"];
|
|
2420
2037
|
/**
|
|
2421
|
-
* Typed client for the query doors (`POST /api/v1/query
|
|
2422
|
-
*
|
|
2423
|
-
*
|
|
2424
|
-
* and saved charts run through, exposed directly rather than only via a saved
|
|
2425
|
-
* chart's statement.
|
|
2426
|
-
*
|
|
2427
|
-
* Unlike the chart family, these routes carry no `projectId` in their path or
|
|
2428
|
-
* body — the generated operations declare `path?: never`. Project scope is
|
|
2429
|
-
* resolved once, when the underlying `LangwatchApiClient` is built
|
|
2430
|
-
* (`createLangWatchApiClient` bakes `scopedProjectId() ?? LANGWATCH_PROJECT_ID`
|
|
2431
|
-
* into that client's `Authorization`/`Basic` header at construction time —
|
|
2432
|
-
* see `src/internal/api/client.ts` and `src/internal/api/auth.ts`). A
|
|
2433
|
-
* per-call `projectId()` resolution the way `ChartsApiService` has one would
|
|
2434
|
-
* therefore be dead code here: there is no URL slot to put it in, and it
|
|
2435
|
-
* cannot retroactively change a header already baked into an existing
|
|
2436
|
-
* client. It would also wrongly force every caller to have a project in
|
|
2437
|
-
* scope — legacy `sk-lw-*` project keys carry their own project identity and
|
|
2438
|
-
* need none (see `buildAuthHeaders`). So this service takes the plain,
|
|
2439
|
-
* project-implicit config `AnalyticsApiService` does, and lets the api
|
|
2440
|
-
* client resolve the credential itself.
|
|
2038
|
+
* Typed client for the LangWatchQL query doors (`POST /api/v1/query` and `GET
|
|
2039
|
+
* /api/v1/query/schema`) — the same governed query surface the workbench and saved charts
|
|
2040
|
+
* run through, exposed directly rather than only via a saved chart's statement.
|
|
2441
2041
|
*/
|
|
2442
2042
|
declare class QueryApiService {
|
|
2443
2043
|
private readonly apiClient;
|
|
@@ -2450,25 +2050,23 @@ declare class QueryApiService {
|
|
|
2450
2050
|
*/
|
|
2451
2051
|
query(params: QueryRunParams): Promise<QueryRunResult>;
|
|
2452
2052
|
/**
|
|
2453
|
-
* Lists the LangWatchQL analytics
|
|
2454
|
-
*
|
|
2455
|
-
*
|
|
2456
|
-
* partition-pruning time column, freshness and a runnable example query.
|
|
2053
|
+
* Lists the LangWatchQL analytics datasets this key may query, with each column's type,
|
|
2054
|
+
* description, the permissions that unlock it, and whether this caller holds them — plus
|
|
2055
|
+
* each dataset's grain, join keys, partition-pruning time column, freshness and a runnable
|
|
2457
2056
|
*/
|
|
2458
2057
|
schema(): Promise<QuerySchemaResult>;
|
|
2459
2058
|
/**
|
|
2460
|
-
* Describes both query languages in one payload: the LangWatchQL schema,
|
|
2461
|
-
*
|
|
2462
|
-
*
|
|
2463
|
-
* question.
|
|
2059
|
+
* Describes both query languages in one payload: the LangWatchQL schema, limits and endpoints,
|
|
2060
|
+
* the trace filter's syntax and fields, worked examples validated in both, and which language
|
|
2061
|
+
* answers which kind of question.
|
|
2464
2062
|
*/
|
|
2465
2063
|
reference(): Promise<QueryReferenceResult>;
|
|
2466
2064
|
}
|
|
2467
2065
|
|
|
2468
|
-
type TriggerResponse = NonNullable<paths["/api/triggers"]["get"]["responses"]["200"]["content"]["application/json"]>[number];
|
|
2469
|
-
type CreateTriggerBody = NonNullable<paths["/api/triggers"]["post"]["requestBody"]>["content"]["application/json"];
|
|
2470
|
-
type UpdateTriggerBody = NonNullable<paths["/api/triggers/{
|
|
2471
|
-
type TriggerDeleteResponse = paths["/api/triggers/{
|
|
2066
|
+
type TriggerResponse = NonNullable<paths["/api/v1/triggers"]["get"]["responses"]["200"]["content"]["application/json"]>[number];
|
|
2067
|
+
type CreateTriggerBody = NonNullable<paths["/api/v1/triggers"]["post"]["requestBody"]>["content"]["application/json"];
|
|
2068
|
+
type UpdateTriggerBody = NonNullable<paths["/api/v1/triggers/{triggerId}"]["patch"]["requestBody"]>["content"]["application/json"];
|
|
2069
|
+
type TriggerDeleteResponse = paths["/api/v1/triggers/{triggerId}"]["delete"]["responses"]["200"]["content"]["application/json"];
|
|
2472
2070
|
declare class TriggersApiService {
|
|
2473
2071
|
private readonly apiClient;
|
|
2474
2072
|
constructor(config?: Pick<InternalConfig, "langwatchApiClient">);
|
|
@@ -2480,10 +2078,10 @@ declare class TriggersApiService {
|
|
|
2480
2078
|
delete(id: string): Promise<TriggerDeleteResponse>;
|
|
2481
2079
|
}
|
|
2482
2080
|
|
|
2483
|
-
type GraphResponse = NonNullable<paths["/api/graphs"]["get"]["responses"]["200"]["content"]["application/json"]>[number];
|
|
2484
|
-
type CreateGraphBody = NonNullable<paths["/api/graphs"]["post"]["requestBody"]>["content"]["application/json"];
|
|
2485
|
-
type UpdateGraphBody = NonNullable<paths["/api/graphs/{id}"]["patch"]["requestBody"]>["content"]["application/json"];
|
|
2486
|
-
type GraphDeleteResponse = paths["/api/graphs/{id}"]["delete"]["responses"]["200"]["content"]["application/json"];
|
|
2081
|
+
type GraphResponse = NonNullable<paths["/api/v1/graphs"]["get"]["responses"]["200"]["content"]["application/json"]>[number];
|
|
2082
|
+
type CreateGraphBody = NonNullable<paths["/api/v1/graphs"]["post"]["requestBody"]>["content"]["application/json"];
|
|
2083
|
+
type UpdateGraphBody = NonNullable<paths["/api/v1/graphs/{id}"]["patch"]["requestBody"]>["content"]["application/json"];
|
|
2084
|
+
type GraphDeleteResponse = paths["/api/v1/graphs/{id}"]["delete"]["responses"]["200"]["content"]["application/json"];
|
|
2487
2085
|
declare class GraphsApiService {
|
|
2488
2086
|
private readonly apiClient;
|
|
2489
2087
|
constructor(config?: Pick<InternalConfig, "langwatchApiClient">);
|
|
@@ -2495,11 +2093,11 @@ declare class GraphsApiService {
|
|
|
2495
2093
|
delete(id: string): Promise<GraphDeleteResponse>;
|
|
2496
2094
|
}
|
|
2497
2095
|
|
|
2498
|
-
type SimulationRunsListResponse = paths["/api/simulation-runs"]["get"]["responses"]["200"]["content"]["application/json"];
|
|
2499
|
-
type SimulationRunResponse = paths["/api/simulation-runs/{scenarioRunId}"]["get"]["responses"]["200"]["content"]["application/json"];
|
|
2500
|
-
type SimulationRunsBatchesListResponse = paths["/api/simulation-runs/batches/list"]["get"]["responses"]["200"]["content"]["application/json"];
|
|
2501
|
-
type SimulationRunsListParams = NonNullable<paths["/api/simulation-runs"]["get"]["parameters"]["query"]>;
|
|
2502
|
-
type SimulationRunsBatchesListParams = paths["/api/simulation-runs/batches/list"]["get"]["parameters"]["query"];
|
|
2096
|
+
type SimulationRunsListResponse = paths["/api/v1/simulation-runs"]["get"]["responses"]["200"]["content"]["application/json"];
|
|
2097
|
+
type SimulationRunResponse = paths["/api/v1/simulation-runs/{scenarioRunId}"]["get"]["responses"]["200"]["content"]["application/json"];
|
|
2098
|
+
type SimulationRunsBatchesListResponse = paths["/api/v1/simulation-runs/batches/list"]["get"]["responses"]["200"]["content"]["application/json"];
|
|
2099
|
+
type SimulationRunsListParams = NonNullable<paths["/api/v1/simulation-runs"]["get"]["parameters"]["query"]>;
|
|
2100
|
+
type SimulationRunsBatchesListParams = paths["/api/v1/simulation-runs/batches/list"]["get"]["parameters"]["query"];
|
|
2503
2101
|
declare class SimulationRunsApiService {
|
|
2504
2102
|
private readonly apiClient;
|
|
2505
2103
|
constructor(config?: Pick<InternalConfig, "langwatchApiClient">);
|
|
@@ -2579,10 +2177,13 @@ interface SecretDeleteResponse {
|
|
|
2579
2177
|
declare class SecretsApiService {
|
|
2580
2178
|
private readonly apiKey;
|
|
2581
2179
|
private readonly endpoint;
|
|
2180
|
+
private readonly configuredProjectId;
|
|
2582
2181
|
constructor(config?: {
|
|
2583
2182
|
apiKey?: string;
|
|
2584
2183
|
endpoint?: string;
|
|
2184
|
+
projectId?: string;
|
|
2585
2185
|
});
|
|
2186
|
+
private projectId;
|
|
2586
2187
|
private request;
|
|
2587
2188
|
getAll(): Promise<SecretResponse[]>;
|
|
2588
2189
|
get(id: string): Promise<SecretResponse>;
|
|
@@ -2597,17 +2198,9 @@ declare class SecretsApiService {
|
|
|
2597
2198
|
}
|
|
2598
2199
|
|
|
2599
2200
|
/**
|
|
2600
|
-
* The per-call options every mutating
|
|
2601
|
-
*
|
|
2602
|
-
*
|
|
2603
|
-
* (`disable(id, { reason })`, `reset(id, { endUserId })`) gains these fields in
|
|
2604
|
-
* that same bag: one bag per call is what a caller expects. A call that takes a
|
|
2605
|
-
* request BODY (`create(input)`, `update(id, input)`) gets a separate trailing
|
|
2606
|
-
* parameter instead, because those body types mirror the wire verbatim and must
|
|
2607
|
-
* not grow keys the wire has never heard of.
|
|
2608
|
-
*
|
|
2609
|
-
* They are an interface rather than a bare `signal` so that the next thing a
|
|
2610
|
-
* call needs per invocation is an added field rather than an added parameter.
|
|
2201
|
+
* The per-call options every mutating billing call takes. An options-bag
|
|
2202
|
+
* call gains these fields there; a body call (`create(input)`) gets them as
|
|
2203
|
+
* a trailing param, since body types mirror the wire verbatim.
|
|
2611
2204
|
*/
|
|
2612
2205
|
/** The request header the control plane deduplicates creates on. */
|
|
2613
2206
|
declare const IDEMPOTENCY_KEY_HEADER = "Idempotency-Key";
|
|
@@ -2626,29 +2219,15 @@ interface MutationOptions {
|
|
|
2626
2219
|
}
|
|
2627
2220
|
interface IdempotentCreateOptions extends MutationOptions {
|
|
2628
2221
|
/**
|
|
2629
|
-
* Makes the create safe to retry
|
|
2630
|
-
*
|
|
2631
|
-
*
|
|
2632
|
-
* retry and the server answers with the first response instead, byte for
|
|
2633
|
-
* byte, including the one-time secret a create hands back.
|
|
2634
|
-
*
|
|
2635
|
-
* Any string of 8 to 255 characters; a UUID minted per logical create is the
|
|
2636
|
-
* usual choice. Receipts answer for 24 hours, and only successful creates
|
|
2637
|
-
* leave one, so a create that failed is safe to run again either way.
|
|
2638
|
-
*
|
|
2639
|
-
* Reusing a key with a DIFFERENT body is refused with `idempotency_error`
|
|
2640
|
-
* rather than quietly answering for the wrong request.
|
|
2222
|
+
* Makes the create safe to retry: the same key replays the first
|
|
2223
|
+
* response verbatim, while a dropped response with no key would mint a
|
|
2224
|
+
* second resource. A DIFFERENT body under the same key is refused.
|
|
2641
2225
|
*/
|
|
2642
2226
|
idempotencyKey?: string;
|
|
2643
2227
|
/**
|
|
2644
|
-
* Called when the response came from a receipt
|
|
2645
|
-
*
|
|
2646
|
-
*
|
|
2647
|
-
* A hook rather than a field on the returned resource: the resource is
|
|
2648
|
-
* identical either way, so nothing about handling it changes, and the
|
|
2649
|
-
* distinction is something a caller logs rather than branches on. Keeping it
|
|
2650
|
-
* off the return type also keeps the wire-shaped entities free of fields the
|
|
2651
|
-
* wire does not have.
|
|
2228
|
+
* Called when the response came from a receipt, not a fresh write. A hook
|
|
2229
|
+
* rather than a resource field, since callers log this rather than branch
|
|
2230
|
+
* on it, keeping wire-shaped entities free of fields the wire lacks.
|
|
2652
2231
|
*/
|
|
2653
2232
|
onIdempotentReplay?: () => void;
|
|
2654
2233
|
}
|
|
@@ -2677,11 +2256,9 @@ interface VirtualKey {
|
|
|
2677
2256
|
display_prefix: string;
|
|
2678
2257
|
principal_user_id: string | null;
|
|
2679
2258
|
/**
|
|
2680
|
-
* Where this key's traces and costs land. Not a scope: it grants no
|
|
2681
|
-
*
|
|
2682
|
-
*
|
|
2683
|
-
* key created before this was stored, in an organization that had no
|
|
2684
|
-
* governance project to fall back to.
|
|
2259
|
+
* Where this key's traces and costs land. Not a scope: it grants no access to the key.
|
|
2260
|
+
* Decided when the key is written and stored on it, so editing what the key is scoped to
|
|
2261
|
+
* never moves it. Null only on a pre-existing key with no governance project fallback.
|
|
2685
2262
|
*/
|
|
2686
2263
|
trace_project_id: string | null;
|
|
2687
2264
|
/**
|
|
@@ -2700,10 +2277,9 @@ interface VirtualKey {
|
|
|
2700
2277
|
last_used_at: string | null;
|
|
2701
2278
|
revoked_at: string | null;
|
|
2702
2279
|
/**
|
|
2703
|
-
* When the key stops serving, or null for a key that never expires.
|
|
2704
|
-
*
|
|
2705
|
-
*
|
|
2706
|
-
* this field rather than the status to tell an expired key apart.
|
|
2280
|
+
* When the key stops serving, or null for a key that never expires. Requests presented
|
|
2281
|
+
* after this moment are refused with `virtual_key_expired`. `status` stays "active" past
|
|
2282
|
+
* the date, so read this field to tell an expired key apart, not status.
|
|
2707
2283
|
*/
|
|
2708
2284
|
expires_at: string | null;
|
|
2709
2285
|
}
|
|
@@ -2752,10 +2328,9 @@ interface CreateVirtualKeyInput {
|
|
|
2752
2328
|
*/
|
|
2753
2329
|
metadata?: Record<string, string>;
|
|
2754
2330
|
/**
|
|
2755
|
-
* Withhold the secret from the response and get a one-time reveal id
|
|
2756
|
-
*
|
|
2757
|
-
*
|
|
2758
|
-
* holds it.
|
|
2331
|
+
* Withhold the secret from the response and get a one-time reveal id instead. The secret is
|
|
2332
|
+
* parked for 24 hours and served once, to the person the key is for, through the LangWatch app;
|
|
2333
|
+
* the caller never holds it.
|
|
2759
2334
|
*/
|
|
2760
2335
|
reveal_once?: boolean;
|
|
2761
2336
|
}
|
|
@@ -2803,10 +2378,9 @@ interface VirtualKeyWithReveal {
|
|
|
2803
2378
|
interface VirtualKeyPage {
|
|
2804
2379
|
data: VirtualKey[];
|
|
2805
2380
|
/**
|
|
2806
|
-
* Pass back as `cursor` for the next page. Null means the walk is
|
|
2807
|
-
*
|
|
2808
|
-
*
|
|
2809
|
-
* than `limit` with more still to come.
|
|
2381
|
+
* Pass back as `cursor` for the next page. Null means the walk is exhausted. Neither page
|
|
2382
|
+
* length tells you anything here: visibility is applied to each page AFTER it is read, so
|
|
2383
|
+
* a page can hold fewer rows than `limit` with more still to come.
|
|
2810
2384
|
*/
|
|
2811
2385
|
next_cursor: string | null;
|
|
2812
2386
|
}
|
|
@@ -2827,32 +2401,29 @@ declare class VirtualKeysApiError extends Error {
|
|
|
2827
2401
|
constructor(message: string, operation: string, originalError?: unknown | undefined);
|
|
2828
2402
|
}
|
|
2829
2403
|
/**
|
|
2830
|
-
* Client for the gateway virtual-key surface (/api/gateway/v1).
|
|
2831
|
-
*
|
|
2832
|
-
*
|
|
2833
|
-
* their fields are lowercase snake_case. Call options this SDK invents (query
|
|
2834
|
-
* filters, per-call behaviour, action arguments) are camelCase like the rest
|
|
2835
|
-
* of the SDK.
|
|
2404
|
+
* Client for the gateway virtual-key surface (/api/gateway/v1). Entity types and the
|
|
2405
|
+
* create/update bodies mirror the wire verbatim (lowercase snake_case); call options this
|
|
2406
|
+
* SDK invents (filters, per-call behaviour, action arguments) are camelCase like the rest.
|
|
2836
2407
|
*/
|
|
2837
2408
|
declare class VirtualKeysApiService {
|
|
2838
2409
|
private readonly endpoint;
|
|
2839
2410
|
private readonly apiKey;
|
|
2411
|
+
/** The project the caller asked for. Sent on every request, where it narrows what is read. */
|
|
2840
2412
|
private readonly projectId;
|
|
2413
|
+
/** Where a key created with no scope lands: the project asked for, else the one resolved. */
|
|
2414
|
+
private readonly defaultProjectId;
|
|
2841
2415
|
constructor(config?: {
|
|
2842
2416
|
endpoint?: string;
|
|
2843
2417
|
apiKey?: string;
|
|
2844
2418
|
projectId?: string;
|
|
2845
2419
|
});
|
|
2420
|
+
private mergedHeaders;
|
|
2846
2421
|
private headers;
|
|
2847
2422
|
private request;
|
|
2848
2423
|
/**
|
|
2849
|
-
* ONE page of the virtual keys visible to the caller, newest first. Pass
|
|
2850
|
-
*
|
|
2851
|
-
*
|
|
2852
|
-
*
|
|
2853
|
-
* `limit` is the page size (server default 50, capped at 200), and it caps
|
|
2854
|
-
* the rows READ, not the rows returned: the visibility filter runs on the
|
|
2855
|
-
* page afterwards. Prefer `list()` unless you mean to page deliberately.
|
|
2424
|
+
* ONE page of the virtual keys visible to the caller, newest first. Pass `next_cursor`
|
|
2425
|
+
* back as `cursor` verbatim — an unrecognized cursor answers 400 rather than restarting.
|
|
2426
|
+
* `limit` caps rows READ, not returned. Prefer `list()` unless paging deliberately.
|
|
2856
2427
|
*/
|
|
2857
2428
|
listPage(options?: {
|
|
2858
2429
|
cursor?: string;
|
|
@@ -2861,17 +2432,9 @@ declare class VirtualKeysApiService {
|
|
|
2861
2432
|
externalId?: string;
|
|
2862
2433
|
}): Promise<VirtualKeyPage>;
|
|
2863
2434
|
/**
|
|
2864
|
-
* Every virtual key visible to the caller
|
|
2865
|
-
*
|
|
2866
|
-
*
|
|
2867
|
-
* The endpoint pages; this follows `next_cursor` until it comes back null.
|
|
2868
|
-
* Stopping on a short page would be wrong here specifically, because the
|
|
2869
|
-
* server filters each page for visibility after reading it, so a page can
|
|
2870
|
-
* hold fewer rows than the limit with more still to come.
|
|
2871
|
-
*
|
|
2872
|
-
* `limit` sizes each request in the walk, it does NOT cap what comes back.
|
|
2873
|
-
* `cursor` resumes an interrupted walk. Take a single page with
|
|
2874
|
-
* `listPage()`, or stream the walk with `iterate()`.
|
|
2435
|
+
* Every virtual key visible to the caller (project, team, or org scoped). Follows
|
|
2436
|
+
* `next_cursor` until null — a short page does NOT mean done, since the visibility filter
|
|
2437
|
+
* runs after each page. `limit` sizes each request, it does not cap the total.
|
|
2875
2438
|
*/
|
|
2876
2439
|
list(options?: {
|
|
2877
2440
|
cursor?: string;
|
|
@@ -2880,11 +2443,9 @@ declare class VirtualKeysApiService {
|
|
|
2880
2443
|
externalId?: string;
|
|
2881
2444
|
}): Promise<VirtualKey[]>;
|
|
2882
2445
|
/**
|
|
2883
|
-
* Every visible virtual key, one row at a time, fetching each page only
|
|
2884
|
-
*
|
|
2885
|
-
*
|
|
2886
|
-
* first. Raises rather than looping forever on a cursor chain that never
|
|
2887
|
-
* ends, exactly like `list()`.
|
|
2446
|
+
* Every visible virtual key, one row at a time, fetching each page only when the
|
|
2447
|
+
* consumer reaches it — stop early and the rest is never read, unlike `list()` which
|
|
2448
|
+
* materialises the whole listing first. Raises rather than looping forever, like `list()`.
|
|
2888
2449
|
*/
|
|
2889
2450
|
iterate(options?: {
|
|
2890
2451
|
cursor?: string;
|
|
@@ -2894,10 +2455,9 @@ declare class VirtualKeysApiService {
|
|
|
2894
2455
|
}): AsyncGenerator<VirtualKey>;
|
|
2895
2456
|
get(id: string): Promise<VirtualKey>;
|
|
2896
2457
|
/**
|
|
2897
|
-
* Mint a key. The response carries the secret ONCE; nothing ever serves it
|
|
2898
|
-
*
|
|
2899
|
-
*
|
|
2900
|
-
* id in place of the secret.
|
|
2458
|
+
* Mint a key. The response carries the secret ONCE; nothing ever serves it again, so a create
|
|
2459
|
+
* that times out is recovered with `idempotencyKey` rather than by listing. With `reveal_once`
|
|
2460
|
+
* the response carries a reveal id in place of the secret.
|
|
2901
2461
|
*/
|
|
2902
2462
|
create(input: CreateVirtualKeyInput & {
|
|
2903
2463
|
reveal_once: true;
|
|
@@ -2912,10 +2472,9 @@ declare class VirtualKeysApiService {
|
|
|
2912
2472
|
} & MutationOptions): Promise<VirtualKey>;
|
|
2913
2473
|
enable(id: string, options?: MutationOptions): Promise<VirtualKey>;
|
|
2914
2474
|
/**
|
|
2915
|
-
* Aggregate spend for one key over a window in epoch milliseconds.
|
|
2916
|
-
*
|
|
2917
|
-
*
|
|
2918
|
-
* construction.
|
|
2475
|
+
* Aggregate spend for one key over a window in epoch milliseconds. Defaults to the
|
|
2476
|
+
* current UTC calendar month server-side. Reads the same cost path the dashboard reads,
|
|
2477
|
+
* so this number and the UI agree by construction.
|
|
2919
2478
|
*/
|
|
2920
2479
|
spend(id: string, options?: {
|
|
2921
2480
|
from?: number;
|
|
@@ -2936,11 +2495,9 @@ interface GatewayBudget {
|
|
|
2936
2495
|
window: BudgetWindow;
|
|
2937
2496
|
on_breach: BudgetOnBreach;
|
|
2938
2497
|
/**
|
|
2939
|
-
* For `group` rows
|
|
2940
|
-
* `
|
|
2941
|
-
*
|
|
2942
|
-
* the PER-PERSON cap, and `end_users_seen` / `end_users_over` carry the
|
|
2943
|
-
* standing instead of `spent_usd`.
|
|
2498
|
+
* For `group` rows, the PER-MEMBER allowance (`member_count` says how many
|
|
2499
|
+
* it covers); for `attributed_user` rows, the PER-PERSON cap, with
|
|
2500
|
+
* `end_users_seen`/`end_users_over` as the standing instead of `spent_usd`.
|
|
2944
2501
|
*/
|
|
2945
2502
|
limit_usd: string;
|
|
2946
2503
|
/** Canonical integer limit, nano-USD. Null past the safe integer range. */
|
|
@@ -2971,11 +2528,9 @@ interface GatewayBudget {
|
|
|
2971
2528
|
end_users_over?: number;
|
|
2972
2529
|
}
|
|
2973
2530
|
/**
|
|
2974
|
-
* One page of the budget listing, exactly as the wire serves it.
|
|
2975
|
-
*
|
|
2976
|
-
*
|
|
2977
|
-
* array because `spend_available` is a correctness flag about the whole page,
|
|
2978
|
-
* and an array cannot carry it.
|
|
2531
|
+
* One page of the budget listing, exactly as the wire serves it. An envelope,
|
|
2532
|
+
* not a bare array, because `spend_available` is a correctness flag about the
|
|
2533
|
+
* whole page and an array cannot carry it.
|
|
2979
2534
|
*/
|
|
2980
2535
|
interface GatewayBudgetPage {
|
|
2981
2536
|
data: GatewayBudget[];
|
|
@@ -3024,10 +2579,9 @@ interface CreateGatewayBudgetInput {
|
|
|
3024
2579
|
/** ModelProvider id to pin the budget to one provider. */
|
|
3025
2580
|
provider_key?: string | null;
|
|
3026
2581
|
/**
|
|
3027
|
-
* RFC3339 instant
|
|
3028
|
-
*
|
|
3029
|
-
*
|
|
3030
|
-
* rejected on the windows that never cycle (`total`, `manual`).
|
|
2582
|
+
* RFC3339 instant phasing the cycle instead of the calendar (a `month`
|
|
2583
|
+
* anchored `2026-01-17T09:00:00Z` rolls every 17th at 09:00 UTC). Immutable
|
|
2584
|
+
* once created; rejected on windows that never cycle (`total`, `manual`).
|
|
3031
2585
|
*/
|
|
3032
2586
|
cycle_anchor_at?: string;
|
|
3033
2587
|
/**
|
|
@@ -3055,12 +2609,9 @@ declare class GatewayBudgetsApiError extends Error {
|
|
|
3055
2609
|
constructor(message: string, operation: string, originalError?: unknown | undefined);
|
|
3056
2610
|
}
|
|
3057
2611
|
/**
|
|
3058
|
-
* Client for the gateway budget surface (/api/gateway/v1).
|
|
3059
|
-
*
|
|
3060
|
-
*
|
|
3061
|
-
* their fields are lowercase snake_case. Call options this SDK invents (query
|
|
3062
|
-
* filters, per-call behaviour, action arguments) are camelCase like the rest
|
|
3063
|
-
* of the SDK.
|
|
2612
|
+
* Client for the gateway budget surface (/api/gateway/v1). Entity/body fields
|
|
2613
|
+
* mirror the wire verbatim (snake_case); options this SDK invents (filters,
|
|
2614
|
+
* per-call behaviour, actions) are camelCase like the rest.
|
|
3064
2615
|
*/
|
|
3065
2616
|
declare class GatewayBudgetsApiService {
|
|
3066
2617
|
private readonly endpoint;
|
|
@@ -3074,13 +2625,9 @@ declare class GatewayBudgetsApiService {
|
|
|
3074
2625
|
private headers;
|
|
3075
2626
|
private request;
|
|
3076
2627
|
/**
|
|
3077
|
-
* ONE page of non-archived budgets
|
|
3078
|
-
*
|
|
3079
|
-
*
|
|
3080
|
-
*
|
|
3081
|
-
* `limit` is the page size (server default 50, capped at 200). Prefer
|
|
3082
|
-
* `list()` unless you mean to page deliberately: a full page is not a
|
|
3083
|
-
* promise of more, and a null `next_cursor` is the only end of the walk.
|
|
2628
|
+
* ONE page of non-archived budgets. Pass `next_cursor` back as `cursor`
|
|
2629
|
+
* verbatim: an unissued cursor answers 400 rather than restarting the walk.
|
|
2630
|
+
* `limit` is the page size (default 50, capped 200) — prefer `list()`.
|
|
3084
2631
|
*/
|
|
3085
2632
|
listPage(options?: {
|
|
3086
2633
|
scopeTypes?: BudgetScopeKind[];
|
|
@@ -3090,24 +2637,9 @@ declare class GatewayBudgetsApiService {
|
|
|
3090
2637
|
externalId?: string;
|
|
3091
2638
|
}): Promise<GatewayBudgetPage>;
|
|
3092
2639
|
/**
|
|
3093
|
-
* Every non-archived budget
|
|
3094
|
-
*
|
|
3095
|
-
*
|
|
3096
|
-
* The endpoint pages; this follows `next_cursor` until it comes back null,
|
|
3097
|
-
* so the result is the complete listing and carries no cursor of its own.
|
|
3098
|
-
* Callers that count, total, or decide an all-clear on this list need that
|
|
3099
|
-
* completeness for correctness, not just for display.
|
|
3100
|
-
*
|
|
3101
|
-
* `limit` sizes each request in the walk, it does NOT cap what comes back.
|
|
3102
|
-
* `cursor` resumes an interrupted walk. Take a single page with
|
|
3103
|
-
* `listPage()`, or stream the walk with `iterate()`.
|
|
3104
|
-
*
|
|
3105
|
-
* A plain array, like every other exhaustive `list()` in the SDK: a walk
|
|
3106
|
-
* that ran to the end has no cursor left to report. Null `spent_usd` /
|
|
3107
|
-
* `spent_nano_usd` on a row is not by itself "spend unavailable": an
|
|
3108
|
-
* `attributed_user` template row serves null deliberately, because one
|
|
3109
|
-
* allowance per person has no single total. Use `listPage()` when you need
|
|
3110
|
-
* `spend_available` stated outright.
|
|
2640
|
+
* Every non-archived budget across all scope types, following `next_cursor`
|
|
2641
|
+
* to completion — callers that count/total need that. Plain array, no
|
|
2642
|
+
* cursor; `limit` sizes requests but doesn't cap the result.
|
|
3111
2643
|
*/
|
|
3112
2644
|
list(options?: {
|
|
3113
2645
|
scopeTypes?: BudgetScopeKind[];
|
|
@@ -3118,10 +2650,8 @@ declare class GatewayBudgetsApiService {
|
|
|
3118
2650
|
}): Promise<GatewayBudget[]>;
|
|
3119
2651
|
/**
|
|
3120
2652
|
* Every non-archived budget, one row at a time, fetching each page only
|
|
3121
|
-
* when the consumer reaches it.
|
|
3122
|
-
*
|
|
3123
|
-
* A null `spent_usd` means spend could not be totalled rather than that
|
|
3124
|
-
* nothing was spent.
|
|
2653
|
+
* when the consumer reaches it. A null `spent_usd` means spend could not
|
|
2654
|
+
* be totalled, not that nothing was spent.
|
|
3125
2655
|
*/
|
|
3126
2656
|
iterate(options?: {
|
|
3127
2657
|
scopeTypes?: BudgetScopeKind[];
|
|
@@ -3131,12 +2661,9 @@ declare class GatewayBudgetsApiService {
|
|
|
3131
2661
|
externalId?: string;
|
|
3132
2662
|
}): AsyncGenerator<GatewayBudget>;
|
|
3133
2663
|
/**
|
|
3134
|
-
* One budget by id, in the same row shape the listing serves.
|
|
3135
|
-
*
|
|
3136
|
-
*
|
|
3137
|
-
* answer 404 today. A null `spent_usd` means spend could not be totalled
|
|
3138
|
-
* rather than that nothing was spent, which is the same signal the listing
|
|
3139
|
-
* carries as `spend_available`.
|
|
2664
|
+
* One budget by id, in the same row shape the listing serves. Archived
|
|
2665
|
+
* budgets are not served, so a budget that existed yesterday can answer
|
|
2666
|
+
* 404 today.
|
|
3140
2667
|
*/
|
|
3141
2668
|
get(id: string): Promise<GatewayBudget>;
|
|
3142
2669
|
create(input: CreateGatewayBudgetInput, options?: IdempotentCreateOptions): Promise<GatewayBudget>;
|
|
@@ -3153,16 +2680,9 @@ declare class GatewayBudgetsApiService {
|
|
|
3153
2680
|
}
|
|
3154
2681
|
|
|
3155
2682
|
/**
|
|
3156
|
-
* The quantities one priced request or rollup carries
|
|
3157
|
-
* present
|
|
3158
|
-
*
|
|
3159
|
-
* The token buckets are disjoint, not nested. An image generation reports its
|
|
3160
|
-
* render under `output_image_tokens` with `output_tokens` at 0, so reading
|
|
3161
|
-
* `output_tokens` alone sees none of the image traffic.
|
|
3162
|
-
*
|
|
3163
|
-
* Every priced quantity is charged once at its own rate. `reasoning_tokens`
|
|
3164
|
-
* is a subset of `output_tokens` and `image_count` is a count of images, so
|
|
3165
|
-
* no rate prices either and neither belongs in a cost sum.
|
|
2683
|
+
* The quantities one priced request or rollup carries; every field is
|
|
2684
|
+
* always present (0 when unused) and buckets are disjoint, not nested.
|
|
2685
|
+
* `reasoning_tokens` and `image_count` are subsets already priced elsewhere.
|
|
3166
2686
|
*/
|
|
3167
2687
|
interface SpendUsage {
|
|
3168
2688
|
input_tokens: number;
|
|
@@ -3228,7 +2748,7 @@ interface SpendSummaryRow {
|
|
|
3228
2748
|
* two dimensions, two rows can share a key: read `group` to tell them apart.
|
|
3229
2749
|
*/
|
|
3230
2750
|
key: string;
|
|
3231
|
-
/** Every grouping dimension by name, e.g. `{ model: "gpt-
|
|
2751
|
+
/** Every grouping dimension by name, e.g. `{ model: "gpt-6-luna" }`. */
|
|
3232
2752
|
group: Record<string, string>;
|
|
3233
2753
|
/** Start of the time bucket in the requested zone, null when unbucketed. */
|
|
3234
2754
|
bucket_start: string | null;
|
|
@@ -3242,30 +2762,15 @@ interface SpendSummaryRow {
|
|
|
3242
2762
|
nano_usd: number;
|
|
3243
2763
|
};
|
|
3244
2764
|
}
|
|
3245
|
-
/**
|
|
3246
|
-
* The states a request can be filtered by, which is more than the two a
|
|
3247
|
-
* caller usually thinks in: a request is `admitted` when it starts,
|
|
3248
|
-
* `confirmed` or `failed` when it ends, and `settled` once its cost is final.
|
|
3249
|
-
* `success` and `error` are the coarse outcome pair over those.
|
|
3250
|
-
*/
|
|
2765
|
+
/** Request states: admitted at start, confirmed/failed/settled at end. */
|
|
3251
2766
|
type SpendEventStatus = "success" | "error" | "admitted" | "confirmed" | "failed" | "settled";
|
|
3252
|
-
/**
|
|
3253
|
-
* The states a ROLLUP can be filtered by. A rollup sums the cost of requests
|
|
3254
|
-
* past admission, so `admitted` is refused there rather than answered with a
|
|
3255
|
-
* zero; list the events to see those. Derived by exclusion so the two stay one
|
|
3256
|
-
* vocabulary.
|
|
3257
|
-
*/
|
|
2767
|
+
/** Rollup states: excludes admitted (no cost yet). Use events for those. */
|
|
3258
2768
|
type SpendSummaryStatus = Exclude<SpendEventStatus, "admitted">;
|
|
3259
2769
|
/** A dimension a rollup can be grouped by. */
|
|
3260
2770
|
type SpendGroupBy = "virtual_key" | "end_user" | "project" | "model" | "provider" | "principal" | "request_type";
|
|
3261
2771
|
/**
|
|
3262
|
-
*
|
|
3263
|
-
*
|
|
3264
|
-
* vocabulary and a divergence can be walked on exactly the narrowing that
|
|
3265
|
-
* produced it.
|
|
3266
|
-
*
|
|
3267
|
-
* Every field takes one value or many; many means "any of these". Naming two
|
|
3268
|
-
* different fields narrows.
|
|
2772
|
+
* Shared filters for spend reads. Every field takes one value or many.
|
|
2773
|
+
* Multiple values widen; multiple fields narrow.
|
|
3269
2774
|
*/
|
|
3270
2775
|
interface SpendFilterOptions {
|
|
3271
2776
|
projectId?: string | string[];
|
|
@@ -3288,24 +2793,12 @@ interface SpendFilterOptions {
|
|
|
3288
2793
|
status?: SpendEventStatus;
|
|
3289
2794
|
}
|
|
3290
2795
|
/**
|
|
3291
|
-
*
|
|
3292
|
-
*
|
|
3293
|
-
*
|
|
3294
|
-
* `gateway_spend_group_by_unstable` over a window recent enough that outcomes
|
|
3295
|
-
* can still arrive: until a request settles, the model and provider recorded
|
|
3296
|
-
* against it are the ones that were asked for, and they are replaced by the
|
|
3297
|
-
* ones that actually served it. A page walk over a group that can move counts
|
|
3298
|
-
* some requests twice and misses others.
|
|
3299
|
-
*
|
|
3300
|
-
* Reconcile closed periods and this never fires. For a live view where an
|
|
3301
|
-
* approximate shape is enough, send `allowUnstable`.
|
|
2796
|
+
* Grouping by model/provider/time is unstable: outcomes may arrive and change
|
|
2797
|
+
* the recorded values. Use allowUnstable for approximate live views; reconcile
|
|
2798
|
+
* closed periods to avoid this.
|
|
3302
2799
|
*/
|
|
3303
2800
|
interface SpendSummariesOptions extends Omit<SpendFilterOptions, "status"> {
|
|
3304
|
-
/**
|
|
3305
|
-
* One lifecycle status, minus `admitted`: a rollup sums the cost of requests
|
|
3306
|
-
* past admission, and an admitted request has none yet. List the events for
|
|
3307
|
-
* those.
|
|
3308
|
-
*/
|
|
2801
|
+
/** Lifecycle status; excludes admitted (no cost yet). */
|
|
3309
2802
|
status?: SpendSummaryStatus;
|
|
3310
2803
|
/** One or two dimensions. Two rows can share `key`; read `group`. */
|
|
3311
2804
|
groupBy: SpendGroupBy | SpendGroupBy[];
|
|
@@ -3373,29 +2866,8 @@ declare class SpendEventsApiError extends Error {
|
|
|
3373
2866
|
constructor(message: string, operation: string, originalError?: unknown | undefined);
|
|
3374
2867
|
}
|
|
3375
2868
|
/**
|
|
3376
|
-
*
|
|
3377
|
-
*
|
|
3378
|
-
*
|
|
3379
|
-
* Entity types mirror the wire verbatim, so their fields are lowercase
|
|
3380
|
-
* snake_case. Call options this SDK invents (query filters, per-call
|
|
3381
|
-
* behaviour, action arguments) are camelCase like the rest of the SDK.
|
|
3382
|
-
*
|
|
3383
|
-
* There is no project id here: `/spend-summaries` takes `project_id` as a
|
|
3384
|
-
* query filter rather than scoping on a header, so the project belongs to the
|
|
3385
|
-
* call, not to the client.
|
|
3386
|
-
*
|
|
3387
|
-
* The key MUST be an organization API key (`sk-lw-{id}_{secret}`, from
|
|
3388
|
-
* Settings > API Keys). A project API key is refused before any permission is
|
|
3389
|
-
* consulted, with `credential_class_mismatch`, and no header makes it work:
|
|
3390
|
-
* these are organization-scoped routes and a project key names one project.
|
|
3391
|
-
* The same organization key also reaches the project-scoped surfaces when
|
|
3392
|
-
* given `X-Project-Id`, so one key covers both families and a project key
|
|
3393
|
-
* covers only one.
|
|
3394
|
-
*
|
|
3395
|
-
* Neither collection on this service offers an eager whole-set read. The
|
|
3396
|
-
* ledger is unbounded, and materialising a window of it is the very
|
|
3397
|
-
* under-counting and out-of-memory footgun the page docstrings warn about:
|
|
3398
|
-
* take pages, or stream with `iterate()` / `iterSummaries()`.
|
|
2869
|
+
* Spend reconciliation service (/api/gateway/v1). Requires ORGANIZATION API
|
|
2870
|
+
* key (sk-lw-*). Use iterate/iterSummaries for large windows (no eager read).
|
|
3399
2871
|
*/
|
|
3400
2872
|
declare class SpendEventsApiService {
|
|
3401
2873
|
private readonly endpoint;
|
|
@@ -3405,15 +2877,7 @@ declare class SpendEventsApiService {
|
|
|
3405
2877
|
apiKey?: string;
|
|
3406
2878
|
});
|
|
3407
2879
|
private request;
|
|
3408
|
-
/**
|
|
3409
|
-
* ONE page of the per-request spend ledger for a window. Pass `next_cursor`
|
|
3410
|
-
* back as `cursor` for the next page, verbatim.
|
|
3411
|
-
*
|
|
3412
|
-
* A full page does NOT mean there is more and a short page does NOT mean
|
|
3413
|
-
* there is no more: only a null cursor ends the walk. A reconciler that
|
|
3414
|
-
* stops on the first page silently under-counts the window, so read every
|
|
3415
|
-
* page or stream them with `iterate()`.
|
|
3416
|
-
*/
|
|
2880
|
+
/** One page of events. Follow next_cursor or use iterate() for the full window. */
|
|
3417
2881
|
listPage(options: SpendFilterOptions & {
|
|
3418
2882
|
/** Required: the pull is a ranged read by contract. */
|
|
3419
2883
|
from: number;
|
|
@@ -3421,15 +2885,7 @@ declare class SpendEventsApiService {
|
|
|
3421
2885
|
cursor?: string;
|
|
3422
2886
|
limit?: number;
|
|
3423
2887
|
}): Promise<SpendEventsPage>;
|
|
3424
|
-
/**
|
|
3425
|
-
* Every spend event in the window, one row at a time, fetching each page
|
|
3426
|
-
* only when the consumer reaches it.
|
|
3427
|
-
*
|
|
3428
|
-
* This is how a reconciler reads a whole window without holding it: the
|
|
3429
|
-
* ledger is unbounded, so there is deliberately no eager `list()` to
|
|
3430
|
-
* collect it into an array. Raises rather than looping forever on a cursor
|
|
3431
|
-
* chain that never ends.
|
|
3432
|
-
*/
|
|
2888
|
+
/** Stream events without holding the whole window in memory. */
|
|
3433
2889
|
iterate(options: SpendFilterOptions & {
|
|
3434
2890
|
/** Required: the pull is a ranged read by contract. */
|
|
3435
2891
|
from: number;
|
|
@@ -3437,38 +2893,17 @@ declare class SpendEventsApiService {
|
|
|
3437
2893
|
cursor?: string;
|
|
3438
2894
|
limit?: number;
|
|
3439
2895
|
}): AsyncGenerator<SpendEvent>;
|
|
3440
|
-
/**
|
|
3441
|
-
* ONE page of per-key spend rollups for a window, paged by group key
|
|
3442
|
-
* ascending.
|
|
3443
|
-
*
|
|
3444
|
-
* The page is a step of a walk, not a whole answer: follow `next_cursor`
|
|
3445
|
-
* until it comes back null, or stream the walk with `iterSummaries()`. A
|
|
3446
|
-
* reconciler that reads only the first page silently under-counts every
|
|
3447
|
-
* tenant past the limit.
|
|
3448
|
-
*/
|
|
2896
|
+
/** One page of rollups by group key. Use iterSummaries for the full walk. */
|
|
3449
2897
|
summariesPage(options: SpendSummariesOptions & {
|
|
3450
2898
|
cursor?: string;
|
|
3451
2899
|
limit?: number;
|
|
3452
2900
|
}): Promise<SpendSummariesPage>;
|
|
3453
|
-
/**
|
|
3454
|
-
* Every rollup row for the window, one at a time, fetching each page only
|
|
3455
|
-
* when the consumer reaches it.
|
|
3456
|
-
*
|
|
3457
|
-
* The rollup has one row per tenant seen in the window, which no bound
|
|
3458
|
-
* covers, so there is deliberately no eager whole-set read here either: a
|
|
3459
|
-
* checksum that quietly covers part of the window is worse than none.
|
|
3460
|
-
*/
|
|
2901
|
+
/** Stream rollup rows without holding the whole window in memory. */
|
|
3461
2902
|
iterSummaries(options: SpendSummariesOptions & {
|
|
3462
2903
|
cursor?: string;
|
|
3463
2904
|
limit?: number;
|
|
3464
2905
|
}): AsyncGenerator<SpendSummaryRow>;
|
|
3465
|
-
/**
|
|
3466
|
-
* Re-deliver a window's spend envelopes to ONE endpoint through the
|
|
3467
|
-
* normal delivery path. Envelope ids are unchanged (your consumer's
|
|
3468
|
-
* dedup key); mind your downstream billing system's finite dedup
|
|
3469
|
-
* window before replaying old ranges. The window is capped server-side
|
|
3470
|
-
* at 7 days per call.
|
|
3471
|
-
*/
|
|
2906
|
+
/** Re-deliver spend envelopes to an endpoint (max 7 days). */
|
|
3472
2907
|
replay(options: {
|
|
3473
2908
|
from: number;
|
|
3474
2909
|
to: number;
|
|
@@ -3547,13 +2982,9 @@ interface CreateWebhookEndpointBase {
|
|
|
3547
2982
|
max_in_flight?: number;
|
|
3548
2983
|
}
|
|
3549
2984
|
/**
|
|
3550
|
-
* The POST body, exactly as the wire takes it.
|
|
3551
|
-
*
|
|
3552
|
-
*
|
|
3553
|
-
* than independent optional fields: the type refuses `{destination_kind:
|
|
3554
|
-
* "sqs"}` with no queue, and `{url, sqs}` together, which is what the server
|
|
3555
|
-
* refuses too. `destination_kind` is optional only on the http branch, where
|
|
3556
|
-
* absent has always meant http.
|
|
2985
|
+
* The POST body, exactly as the wire takes it. A destination is one kind and
|
|
2986
|
+
* one address, so the two are a union, matching what the server refuses too.
|
|
2987
|
+
* `destination_kind` is optional only on the http branch (absent means http).
|
|
3557
2988
|
*/
|
|
3558
2989
|
type WebhookDestinationInput = {
|
|
3559
2990
|
destination_kind?: "http";
|
|
@@ -3648,24 +3079,9 @@ declare class WebhooksApiError extends Error {
|
|
|
3648
3079
|
constructor(message: string, operation: string, originalError?: unknown | undefined);
|
|
3649
3080
|
}
|
|
3650
3081
|
/**
|
|
3651
|
-
* Client for the org-anchored webhook platform surface (/api/webhooks/v1)
|
|
3652
|
-
*
|
|
3653
|
-
*
|
|
3654
|
-
* so there is no project id to give this client.
|
|
3655
|
-
*
|
|
3656
|
-
* The key MUST be an organization API key (`sk-lw-{id}_{secret}`, from
|
|
3657
|
-
* Settings > API Keys). A project API key is refused with
|
|
3658
|
-
* `credential_class_mismatch` before any permission is consulted, and no
|
|
3659
|
-
* header makes it work. The same organization key also reaches the
|
|
3660
|
-
* project-scoped surfaces when given `X-Project-Id`, so one key covers both
|
|
3661
|
-
* families and a project key covers only one.
|
|
3662
|
-
*
|
|
3663
|
-
* The endpoint entity and the create/update bodies mirror the wire verbatim,
|
|
3664
|
-
* so their fields are lowercase snake_case: virtual keys and gateway budgets
|
|
3665
|
-
* already take the wire body as it is, and translating field by field here
|
|
3666
|
-
* only made the request bodies of the four billing surfaces disagree. Call
|
|
3667
|
-
* options this SDK invents (query filters, per-call behaviour, action
|
|
3668
|
-
* arguments) stay camelCase like the rest of the SDK.
|
|
3082
|
+
* Client for the org-anchored webhook platform surface (/api/webhooks/v1) — an ORGANIZATION
|
|
3083
|
+
* API key only; a project key is refused with `credential_class_mismatch`. Fields mirror the
|
|
3084
|
+
* wire verbatim in snake_case, since translating field-by-field made billing surfaces disagree.
|
|
3669
3085
|
*/
|
|
3670
3086
|
declare class WebhooksApiService {
|
|
3671
3087
|
private readonly endpoint;
|
|
@@ -3685,25 +3101,17 @@ declare class WebhooksApiService {
|
|
|
3685
3101
|
create(input: CreateWebhookEndpointInput, options?: IdempotentCreateOptions): Promise<WebhookEndpointWithSecret>;
|
|
3686
3102
|
update(id: string, input: UpdateWebhookEndpointInput, options?: MutationOptions): Promise<WebhookEndpointSummary>;
|
|
3687
3103
|
/**
|
|
3688
|
-
* Retire an endpoint: the server soft-archives the row
|
|
3689
|
-
*
|
|
3690
|
-
*
|
|
3691
|
-
* row is archived, not removed, and `gatewayBudgets.archive()` already
|
|
3692
|
-
* names that operation, so the billing surfaces agree on the verb.
|
|
3693
|
-
*
|
|
3694
|
-
* Nothing comes back: the response body carries only an `archived: true`
|
|
3695
|
-
* acknowledgement, and a non-2xx already raises.
|
|
3104
|
+
* Retire an endpoint: the server soft-archives the row (stamping `archived_at`, disabling
|
|
3105
|
+
* delivery) so history stays readable for audit. Archived, not removed — same verb as
|
|
3106
|
+
* `gatewayBudgets.archive()`, so the billing surfaces agree.
|
|
3696
3107
|
*/
|
|
3697
3108
|
archive(id: string, options?: MutationOptions): Promise<void>;
|
|
3698
3109
|
rollSecret(id: string, options?: MutationOptions): Promise<WebhookEndpointWithSecret>;
|
|
3699
3110
|
test(id: string, options?: MutationOptions): Promise<WebhookTestResult>;
|
|
3700
3111
|
/**
|
|
3701
|
-
* ONE page of the endpoint's delivery attempts, newest first.
|
|
3702
|
-
*
|
|
3703
|
-
*
|
|
3704
|
-
* dropping it truncated the delivery log at whatever the first page held,
|
|
3705
|
-
* with nothing in the result to say the rest existed. Pass `next_cursor`
|
|
3706
|
-
* back as `cursor`, or walk the whole log with `iterDeliveries()`.
|
|
3112
|
+
* ONE page of the endpoint's delivery attempts, newest first. Pass
|
|
3113
|
+
* `next_cursor` back as `cursor` for the next page, or walk the whole log
|
|
3114
|
+
* with `iterDeliveries()`.
|
|
3707
3115
|
*/
|
|
3708
3116
|
deliveriesPage(id: string, options?: {
|
|
3709
3117
|
cursor?: string;
|
|
@@ -3721,10 +3129,8 @@ declare class WebhooksApiService {
|
|
|
3721
3129
|
eventTypes(): Promise<WebhookEventType[]>;
|
|
3722
3130
|
/**
|
|
3723
3131
|
* ONE page of the organization's emitted-events log, newest first.
|
|
3724
|
-
*
|
|
3725
|
-
*
|
|
3726
|
-
* that missed a delivery reads the window back from here. Walk the whole
|
|
3727
|
-
* window with `iterEvents()`.
|
|
3132
|
+
* Webhooks are a push over this log, never the only copy: a consumer that
|
|
3133
|
+
* missed a delivery reads the window back from here.
|
|
3728
3134
|
*/
|
|
3729
3135
|
eventsPage(options: {
|
|
3730
3136
|
type?: string;
|
|
@@ -3747,21 +3153,17 @@ declare class WebhooksApiService {
|
|
|
3747
3153
|
limit?: number;
|
|
3748
3154
|
}): AsyncGenerator<EmittedEvent>;
|
|
3749
3155
|
/**
|
|
3750
|
-
* One emitted event by id, the envelope exactly as it was delivered.
|
|
3751
|
-
*
|
|
3752
|
-
*
|
|
3753
|
-
* retention horizon, or belonging to another organization.
|
|
3156
|
+
* One emitted event by id, the envelope exactly as it was delivered. A 404
|
|
3157
|
+
* covers every reason the log cannot answer: never emitted, past
|
|
3158
|
+
* retention, or belonging to another organization.
|
|
3754
3159
|
*/
|
|
3755
3160
|
getEvent(id: string): Promise<EmittedEvent>;
|
|
3756
3161
|
}
|
|
3757
3162
|
|
|
3758
3163
|
/**
|
|
3759
|
-
* The vocabulary the management REST families share on the wire
|
|
3760
|
-
*
|
|
3761
|
-
*
|
|
3762
|
-
* roles, role bindings, groups, teams and API keys. Declared once here so the
|
|
3763
|
-
* CLI's flag parsers validate against one list rather than five copies that
|
|
3764
|
-
* can disagree with the platform.
|
|
3164
|
+
* The vocabulary the management REST families share on the wire: the same
|
|
3165
|
+
* three words appear on roles, bindings, groups, teams and API keys.
|
|
3166
|
+
* Declared once so flag parsers validate against one list, not five.
|
|
3765
3167
|
*/
|
|
3766
3168
|
/** The role a binding grants at its scope. `CUSTOM` defers to a custom role. */
|
|
3767
3169
|
declare const MANAGEMENT_ROLES: readonly ["ADMIN", "MEMBER", "VIEWER", "CUSTOM"];
|
|
@@ -3814,7 +3216,7 @@ declare class TeamsApiService {
|
|
|
3814
3216
|
create(input: {
|
|
3815
3217
|
name: string;
|
|
3816
3218
|
}): Promise<Team>;
|
|
3817
|
-
update({ id, input
|
|
3219
|
+
update({ id, input }: {
|
|
3818
3220
|
id: string;
|
|
3819
3221
|
input: {
|
|
3820
3222
|
name?: string;
|
|
@@ -3864,6 +3266,12 @@ interface UpdateProjectInput {
|
|
|
3864
3266
|
language?: string;
|
|
3865
3267
|
framework?: string;
|
|
3866
3268
|
piiRedactionLevel?: "STRICT" | "ESSENTIAL" | "DISABLED";
|
|
3269
|
+
/**
|
|
3270
|
+
* Moves the project to this team. The platform refuses a team outside the
|
|
3271
|
+
* organization, an archived one, and a move across the personal workspace
|
|
3272
|
+
* boundary.
|
|
3273
|
+
*/
|
|
3274
|
+
teamId?: string;
|
|
3867
3275
|
}
|
|
3868
3276
|
interface ProjectWithServiceKey extends Project {
|
|
3869
3277
|
serviceApiKey: string;
|
|
@@ -3887,18 +3295,16 @@ declare class ProjectsApiError extends Error {
|
|
|
3887
3295
|
readonly operation: string;
|
|
3888
3296
|
readonly originalError?: unknown | undefined;
|
|
3889
3297
|
/**
|
|
3890
|
-
* The status the platform answered with.
|
|
3891
|
-
*
|
|
3892
|
-
*
|
|
3893
|
-
* answer to the user than "no project of yours matches this name".
|
|
3298
|
+
* The status the platform answered with. A 401/403 means the credential
|
|
3299
|
+
* cannot see the listing at all -- a different answer than "no project
|
|
3300
|
+
* of yours matches this name".
|
|
3894
3301
|
*/
|
|
3895
3302
|
readonly status?: number | undefined;
|
|
3896
3303
|
constructor(message: string, operation: string, originalError?: unknown | undefined,
|
|
3897
3304
|
/**
|
|
3898
|
-
* The status the platform answered with.
|
|
3899
|
-
*
|
|
3900
|
-
*
|
|
3901
|
-
* answer to the user than "no project of yours matches this name".
|
|
3305
|
+
* The status the platform answered with. A 401/403 means the credential
|
|
3306
|
+
* cannot see the listing at all -- a different answer than "no project
|
|
3307
|
+
* of yours matches this name".
|
|
3902
3308
|
*/
|
|
3903
3309
|
status?: number | undefined);
|
|
3904
3310
|
}
|
|
@@ -3910,11 +3316,9 @@ declare class ProjectsApiService {
|
|
|
3910
3316
|
apiKey?: string;
|
|
3911
3317
|
});
|
|
3912
3318
|
/**
|
|
3913
|
-
* Bearer, never the project-pinned Basic shape the
|
|
3914
|
-
*
|
|
3915
|
-
*
|
|
3916
|
-
* and defeat the call — including the `--project <slug>` lookup, which reads
|
|
3917
|
-
* the listing precisely because it does not know the id yet.
|
|
3319
|
+
* Bearer, never the project-pinned Basic shape: the listing asks "which
|
|
3320
|
+
* projects can this credential see?", so naming one project in the header
|
|
3321
|
+
* would scope the answer and defeat the call, including `--project <slug>`.
|
|
3918
3322
|
*/
|
|
3919
3323
|
private headers;
|
|
3920
3324
|
private request;
|
|
@@ -3937,17 +3341,107 @@ declare class ProjectsApiService {
|
|
|
3937
3341
|
interface GetTraceParams {
|
|
3938
3342
|
includeSpans?: boolean;
|
|
3939
3343
|
}
|
|
3940
|
-
|
|
3344
|
+
/** The error block a trace or one of its parts carries when it failed. */
|
|
3345
|
+
interface TraceErrorCapture {
|
|
3346
|
+
stacktrace?: string[];
|
|
3347
|
+
message?: string;
|
|
3348
|
+
has_error?: boolean;
|
|
3349
|
+
}
|
|
3350
|
+
/** One message in a span's chat input or output. */
|
|
3351
|
+
interface TraceChatMessage {
|
|
3352
|
+
role?: string;
|
|
3353
|
+
content?: string;
|
|
3354
|
+
}
|
|
3355
|
+
/** One span of a trace, as the trace read answers it. */
|
|
3356
|
+
interface TraceSpan {
|
|
3357
|
+
trace_id?: string;
|
|
3358
|
+
span_id?: string;
|
|
3359
|
+
project_id?: string;
|
|
3360
|
+
parent_id?: string | null;
|
|
3361
|
+
name?: string | null;
|
|
3362
|
+
type?: string;
|
|
3363
|
+
model?: string;
|
|
3364
|
+
timestamps?: {
|
|
3365
|
+
started_at?: number;
|
|
3366
|
+
first_token_at?: number;
|
|
3367
|
+
finished_at?: number;
|
|
3368
|
+
inserted_at?: number;
|
|
3369
|
+
updated_at?: number;
|
|
3370
|
+
};
|
|
3371
|
+
error?: TraceErrorCapture | null;
|
|
3372
|
+
params?: {
|
|
3373
|
+
stream?: boolean;
|
|
3374
|
+
temperature?: number;
|
|
3375
|
+
};
|
|
3376
|
+
metrics?: {
|
|
3377
|
+
prompt_tokens?: number;
|
|
3378
|
+
completion_tokens?: number;
|
|
3379
|
+
tokens_estimated?: boolean;
|
|
3380
|
+
};
|
|
3381
|
+
input?: {
|
|
3382
|
+
type?: string;
|
|
3383
|
+
value?: TraceChatMessage[];
|
|
3384
|
+
};
|
|
3385
|
+
output?: {
|
|
3386
|
+
type?: string;
|
|
3387
|
+
value?: TraceChatMessage[];
|
|
3388
|
+
};
|
|
3389
|
+
}
|
|
3390
|
+
/** One evaluation recorded against a trace. */
|
|
3391
|
+
interface TraceEvaluation {
|
|
3392
|
+
evaluation_id?: string;
|
|
3393
|
+
name?: string;
|
|
3394
|
+
type?: string;
|
|
3395
|
+
trace_id?: string;
|
|
3396
|
+
project_id?: string;
|
|
3397
|
+
status?: string;
|
|
3398
|
+
timestamps?: {
|
|
3399
|
+
inserted_at?: number;
|
|
3400
|
+
updated_at?: number;
|
|
3401
|
+
};
|
|
3402
|
+
error?: TraceErrorCapture;
|
|
3403
|
+
}
|
|
3404
|
+
/**
|
|
3405
|
+
* A single trace with its spans and evaluations. Hand-declared because the
|
|
3406
|
+
* served OpenAPI document describes this answer as a free-form object, so the
|
|
3407
|
+
* generated client cannot carry the shape callers read.
|
|
3408
|
+
*/
|
|
3409
|
+
interface GetTraceResponse {
|
|
3410
|
+
trace_id?: string;
|
|
3411
|
+
project_id?: string;
|
|
3412
|
+
metadata?: {
|
|
3413
|
+
sdk_version?: string;
|
|
3414
|
+
sdk_language?: string;
|
|
3415
|
+
};
|
|
3416
|
+
timestamps?: {
|
|
3417
|
+
started_at?: number;
|
|
3418
|
+
inserted_at?: number;
|
|
3419
|
+
updated_at?: number;
|
|
3420
|
+
};
|
|
3421
|
+
input?: {
|
|
3422
|
+
value?: string;
|
|
3423
|
+
};
|
|
3424
|
+
output?: {
|
|
3425
|
+
value?: string;
|
|
3426
|
+
};
|
|
3427
|
+
error?: TraceErrorCapture | null;
|
|
3428
|
+
indexing_md5s?: string[];
|
|
3429
|
+
spans?: TraceSpan[];
|
|
3430
|
+
evaluations?: TraceEvaluation[];
|
|
3431
|
+
}
|
|
3941
3432
|
|
|
3433
|
+
/** `langwatch.traces`: the CLI's trace read, traced. Failures throw `TracesApiError`. */
|
|
3942
3434
|
declare class TracesFacade {
|
|
3943
3435
|
#private;
|
|
3944
3436
|
constructor(config: InternalConfig);
|
|
3945
|
-
|
|
3437
|
+
/** `params` stays for compatibility; the endpoint takes no such option and never got one. */
|
|
3438
|
+
get(traceId: string, _params?: GetTraceParams): Promise<GetTraceResponse>;
|
|
3946
3439
|
}
|
|
3947
3440
|
|
|
3948
3441
|
interface LangWatchConstructorOptions {
|
|
3949
3442
|
apiKey?: string;
|
|
3950
3443
|
endpoint?: string;
|
|
3444
|
+
projectId?: string;
|
|
3951
3445
|
options?: {
|
|
3952
3446
|
logger?: Logger;
|
|
3953
3447
|
};
|
|
@@ -3960,41 +3454,17 @@ declare class LangWatch {
|
|
|
3960
3454
|
readonly datasets: DatasetsFacade;
|
|
3961
3455
|
/**
|
|
3962
3456
|
* Run experiments on LangWatch platform or via SDK.
|
|
3963
|
-
*
|
|
3964
|
-
* Platform experiments (CI/CD):
|
|
3965
|
-
* ```typescript
|
|
3966
|
-
* const result = await langwatch.experiments.run("my-experiment-slug");
|
|
3967
|
-
* result.printSummary();
|
|
3968
|
-
* ```
|
|
3969
|
-
*
|
|
3970
|
-
* SDK-defined experiments:
|
|
3971
|
-
* ```typescript
|
|
3972
|
-
* const experiment = await langwatch.experiments.init("my-experiment");
|
|
3973
|
-
* // ... run evaluators using experiment.evaluate()
|
|
3974
|
-
* ```
|
|
3975
3457
|
*/
|
|
3976
3458
|
readonly experiments: ExperimentsFacade;
|
|
3977
3459
|
/**
|
|
3978
3460
|
* Run evaluators and guardrails in real-time (Online Evaluations).
|
|
3979
|
-
*
|
|
3980
3461
|
* @example
|
|
3981
|
-
* ```typescript
|
|
3982
|
-
* const guardrail = await langwatch.evaluations.evaluate("presidio/pii_detection", {
|
|
3983
|
-
* data: { input: userInput, output: generatedResponse },
|
|
3984
|
-
* name: "PII Detection",
|
|
3985
|
-
* asGuardrail: true,
|
|
3986
|
-
* });
|
|
3987
|
-
*
|
|
3988
|
-
* if (!guardrail.passed) {
|
|
3989
|
-
* return "I'm sorry, I can't do that.";
|
|
3990
|
-
* }
|
|
3991
|
-
* ```
|
|
3992
3462
|
*/
|
|
3993
3463
|
readonly evaluations: EvaluationsFacade;
|
|
3994
3464
|
readonly evaluators: EvaluatorsApiService;
|
|
3995
3465
|
readonly scenarios: ScenariosApiService;
|
|
3996
3466
|
/**
|
|
3997
|
-
* @deprecated Use runPlans and testSuites; /api/suites is a frozen alias.
|
|
3467
|
+
* @deprecated Use runPlans and testSuites; /api/v1/suites is a frozen alias.
|
|
3998
3468
|
*/
|
|
3999
3469
|
readonly suites: SuitesApiService;
|
|
4000
3470
|
readonly runPlans: RunPlansApiService;
|
|
@@ -4004,10 +3474,13 @@ declare class LangWatch {
|
|
|
4004
3474
|
readonly workflows: WorkflowsApiService;
|
|
4005
3475
|
readonly agents: AgentsApiService;
|
|
4006
3476
|
readonly annotations: AnnotationsApiService;
|
|
3477
|
+
/** The project's dashboards and the widgets on them, over /api/v1/dashboards. */
|
|
4007
3478
|
readonly dashboards: DashboardsApiService;
|
|
3479
|
+
/** The Analytics Reports, over /api/v1/analytics/reports; the platform deprecates them. */
|
|
3480
|
+
readonly analyticsReports: AnalyticsReportsApiService;
|
|
4008
3481
|
readonly modelProviders: ModelProvidersApiService;
|
|
4009
3482
|
readonly analytics: AnalyticsApiService;
|
|
4010
|
-
/** The raw LangWatchQL door
|
|
3483
|
+
/** The raw LangWatchQL door: a governed SELECT or schema discovery outside a saved chart. */
|
|
4011
3484
|
readonly query: QueryApiService;
|
|
4012
3485
|
readonly triggers: TriggersApiService;
|
|
4013
3486
|
readonly graphs: GraphsApiService;
|
|
@@ -4021,13 +3494,8 @@ declare class LangWatch {
|
|
|
4021
3494
|
constructor(options?: LangWatchConstructorOptions);
|
|
4022
3495
|
get apiClient(): LangwatchApiClient;
|
|
4023
3496
|
/**
|
|
4024
|
-
* Teams, which group projects and the members who can reach them. These
|
|
4025
|
-
*
|
|
4026
|
-
*
|
|
4027
|
-
* Built on first use rather than in the constructor: the management
|
|
4028
|
-
* families resolve their credential when constructed and refuse an empty
|
|
4029
|
-
* one, so building this eagerly would make `new LangWatch()` throw for
|
|
4030
|
-
* every caller that never touches a team.
|
|
3497
|
+
* Teams, which group projects and the members who can reach them. These routes want an
|
|
3498
|
+
* organization API key.
|
|
4031
3499
|
*/
|
|
4032
3500
|
get teams(): TeamsApiService;
|
|
4033
3501
|
/**
|
|
@@ -4039,43 +3507,10 @@ declare class LangWatch {
|
|
|
4039
3507
|
|
|
4040
3508
|
/**
|
|
4041
3509
|
* A failure the platform NAMED.
|
|
4042
|
-
*
|
|
4043
|
-
* The API does not merely fail — when it declines a request it says precisely
|
|
4044
|
-
* why, as a `HandledError` with a serialisable `kind` (`dataset_not_found`,
|
|
4045
|
-
* `validation_error`), the HTTP status it answers with, and a `meta` bag of the
|
|
4046
|
-
* context that makes the failure actionable. Until now the SDK collapsed all of
|
|
4047
|
-
* that into an English sentence on a generic error, so a caller could read the
|
|
4048
|
-
* failure but never react to it: a 404 "dataset not found" — a fact you can
|
|
4049
|
-
* offer to fix — was indistinguishable from a 500.
|
|
4050
|
-
*
|
|
4051
|
-
* This is that structure, kept. Narrow with {@link isLangWatchHandledError} (or
|
|
4052
|
-
* `instanceof`) and switch on `code`; `body` is the escape hatch to whatever the
|
|
4053
|
-
* platform sent that this class did not model.
|
|
4054
|
-
*
|
|
4055
|
-
* ```ts
|
|
4056
|
-
* try {
|
|
4057
|
-
* await langwatch.datasets.get("nope");
|
|
4058
|
-
* } catch (error) {
|
|
4059
|
-
* if (isLangWatchHandledError(error) && error.code === "dataset_not_found") {
|
|
4060
|
-
* // Actionable: we know WHAT was not found, and can offer the list.
|
|
4061
|
-
* console.error(error.meta.id, error.traceId);
|
|
4062
|
-
* }
|
|
4063
|
-
* throw error;
|
|
4064
|
-
* }
|
|
4065
|
-
* ```
|
|
4066
|
-
*
|
|
4067
|
-
* ONLY raised for a failure the platform named. An infrastructure failure — a
|
|
4068
|
-
* 5xx, a dead socket, a proxy's HTML error page — still raises the generic
|
|
4069
|
-
* service error it always did, because presenting one of those as a domain
|
|
4070
|
-
* error would blame the user for our outage.
|
|
4071
3510
|
*/
|
|
4072
3511
|
declare class LangWatchHandledError extends Error {
|
|
4073
3512
|
/**
|
|
4074
|
-
* The discriminant.
|
|
4075
|
-
* bundled CLI and a consumer's `node_modules` copy of the SDK can hold two
|
|
4076
|
-
* different copies of this class, and `instanceof` is false across that seam —
|
|
4077
|
-
* the same reason the platform's own error handler tests for `code` rather
|
|
4078
|
-
* than class identity.
|
|
3513
|
+
* The discriminant.
|
|
4079
3514
|
*/
|
|
4080
3515
|
readonly isLangWatchHandledError: true;
|
|
4081
3516
|
/** The platform's serialisable discriminant, e.g. `dataset_not_found`. */
|
|
@@ -4096,7 +3531,9 @@ declare class LangWatchHandledError extends Error {
|
|
|
4096
3531
|
/** A clickable link to the logs for that trace, when the route sent one. */
|
|
4097
3532
|
readonly logsUrl: string | undefined;
|
|
4098
3533
|
/** The failure behind the failure, when the route sent the chain. */
|
|
4099
|
-
readonly reasons:
|
|
3534
|
+
readonly reasons: LangWatchHandledErrorReason[] | undefined;
|
|
3535
|
+
/** Whether the platform explicitly marked this failure safe to retry. */
|
|
3536
|
+
readonly retryable: boolean;
|
|
4100
3537
|
/** What the user can DO about it, when the platform sent next steps. */
|
|
4101
3538
|
readonly suggestions: string[] | undefined;
|
|
4102
3539
|
/** The docs page that explains the failure, when the platform sent one. */
|
|
@@ -4106,18 +3543,13 @@ declare class LangWatchHandledError extends Error {
|
|
|
4106
3543
|
/** What the SDK was doing, e.g. `get dataset "abc"`. */
|
|
4107
3544
|
readonly operation: string | undefined;
|
|
4108
3545
|
/**
|
|
4109
|
-
* Alias of {@link httpStatus}, and the raw body again under the name the
|
|
4110
|
-
*
|
|
4111
|
-
*
|
|
4112
|
-
* Not redundancy for its own sake: this class is thrown from the SAME code
|
|
4113
|
-
* path that used to throw `TracesApiError` & friends, so anything that reads
|
|
4114
|
-
* `.status` or `.originalError` off a caught SDK error — including the CLI's
|
|
4115
|
-
* own telemetry reader — keeps working unchanged.
|
|
3546
|
+
* Alias of {@link httpStatus}, and the raw body again under the name the per-service
|
|
3547
|
+
* `*ApiError` classes use.
|
|
4116
3548
|
*/
|
|
4117
3549
|
readonly status: number;
|
|
4118
3550
|
readonly originalError: unknown;
|
|
4119
3551
|
constructor({ handled, body, operation, message, }: {
|
|
4120
|
-
handled:
|
|
3552
|
+
handled: LangWatchHandledErrorShape;
|
|
4121
3553
|
body: unknown;
|
|
4122
3554
|
operation?: string;
|
|
4123
3555
|
message: string;
|
|
@@ -4135,43 +3567,22 @@ declare class LangWatchApiError extends Error {
|
|
|
4135
3567
|
}
|
|
4136
3568
|
|
|
4137
3569
|
/**
|
|
4138
|
-
*
|
|
4139
|
-
*
|
|
4140
|
-
*
|
|
4141
|
-
*
|
|
4142
|
-
* X-LangWatch-Signature: t=<unix seconds>,v1=<hex hmac-sha256>[,v1=<hex>]
|
|
4143
|
-
*
|
|
4144
|
-
* where each `v1` is HMAC-SHA256 over `"<t>.<raw body>"` under one currently
|
|
4145
|
-
* valid signing secret. `v1` REPEATS during a secret rotation, newest first,
|
|
4146
|
-
* which is what lets a receiver swap secrets on its own schedule instead of
|
|
4147
|
-
* dropping deliveries mid-swap.
|
|
4148
|
-
*
|
|
4149
|
-
* That repetition is the reason this helper exists. A hand-rolled parser that
|
|
4150
|
-
* keeps the LAST `v1` it sees, or splits the header into a flat key/value map,
|
|
4151
|
-
* rejects every delivery to a receiver that has already moved to the new
|
|
4152
|
-
* secret: the signature it kept is the one computed from the OLD secret. The
|
|
4153
|
-
* bug only appears during a rotation, which is exactly when a receiver can
|
|
4154
|
-
* least afford to be dropping deliveries.
|
|
4155
|
-
*
|
|
4156
|
-
* The algorithm here is pinned to the sender's by the vectors in
|
|
4157
|
-
* `specs/webhooks/signature-vectors.json`, generated from the server's own
|
|
4158
|
-
* signing code and asserted by the suite next to this file.
|
|
3570
|
+
* Verify webhook delivery signature in X-LangWatch-Signature header.
|
|
3571
|
+
* Handles secret rotation: v1 repeats with newest first.
|
|
3572
|
+
* Pinned to sender's algorithm by specs/webhooks/signature-vectors.json.
|
|
4159
3573
|
*/
|
|
4160
3574
|
/** The header a delivery carries its signature in. */
|
|
4161
3575
|
declare const WEBHOOK_SIGNATURE_HEADER = "X-LangWatch-Signature";
|
|
4162
3576
|
/**
|
|
4163
|
-
* Identifies one delivery ATTEMPT on the webhook platform's endpoints.
|
|
4164
|
-
*
|
|
4165
|
-
*
|
|
4166
|
-
* it, so a receiver that has already processed this id can acknowledge and
|
|
4167
|
-
* stop rather than applying the batch twice.
|
|
3577
|
+
* Identifies one delivery ATTEMPT on the webhook platform's endpoints. The
|
|
3578
|
+
* natural idempotency key: retries of the same batch repeat it, so a
|
|
3579
|
+
* receiver that already processed this id can stop, not apply it twice.
|
|
4168
3580
|
*/
|
|
4169
3581
|
declare const WEBHOOK_DELIVERY_ID_HEADER = "X-LangWatch-Delivery-Id";
|
|
4170
3582
|
/**
|
|
4171
3583
|
* The same role on automation deliveries (graph alerts and friends), which
|
|
4172
|
-
* group
|
|
4173
|
-
*
|
|
4174
|
-
* Two names because they are two senders: read whichever the delivery carries.
|
|
3584
|
+
* group attempts by the logical fire rather than the batch. Two names
|
|
3585
|
+
* because they are two senders: read whichever the delivery carries.
|
|
4175
3586
|
*/
|
|
4176
3587
|
declare const WEBHOOK_EVENT_ID_HEADER = "X-LangWatch-Event-Id";
|
|
4177
3588
|
/**
|
|
@@ -4180,22 +3591,12 @@ declare const WEBHOOK_EVENT_ID_HEADER = "X-LangWatch-Event-Id";
|
|
|
4180
3591
|
*/
|
|
4181
3592
|
declare const WEBHOOK_SIGNATURE_DEFAULT_TOLERANCE_SECONDS = 300;
|
|
4182
3593
|
/**
|
|
4183
|
-
* Why a delivery was refused
|
|
4184
|
-
*
|
|
4185
|
-
* the contract.
|
|
4186
|
-
*
|
|
4187
|
-
* The three mean genuinely different things to an operator. `stale_timestamp`
|
|
4188
|
-
* is a clock or a replay and is worth alerting on; `invalid_signature` is a
|
|
4189
|
-
* wrong secret or a tampered body; `malformed_header` is almost always
|
|
4190
|
-
* something other than LangWatch posting to the URL.
|
|
3594
|
+
* Why a delivery was refused: malformed_header, stale_timestamp, invalid_signature.
|
|
3595
|
+
* Switch on code, not message; message is for logs and may change.
|
|
4191
3596
|
*/
|
|
4192
3597
|
type WebhookSignatureFailureCode = "malformed_header" | "stale_timestamp" | "invalid_signature";
|
|
4193
3598
|
/**
|
|
4194
|
-
* A delivery that did not verify.
|
|
4195
|
-
*
|
|
4196
|
-
* One class carrying a `code` rather than three classes, because the SDK and
|
|
4197
|
-
* the platform both ask callers to branch on a stable code instead of on the
|
|
4198
|
-
* error's identity, which does not survive a serialization boundary.
|
|
3599
|
+
* A delivery that did not verify. Use code, not error type, to branch logic.
|
|
4199
3600
|
*/
|
|
4200
3601
|
declare class WebhookSignatureVerificationError extends Error {
|
|
4201
3602
|
readonly code: WebhookSignatureFailureCode;
|
|
@@ -4203,22 +3604,17 @@ declare class WebhookSignatureVerificationError extends Error {
|
|
|
4203
3604
|
}
|
|
4204
3605
|
interface VerifyWebhookSignatureOptions {
|
|
4205
3606
|
/**
|
|
4206
|
-
* The EXACT bytes of the request body, as received
|
|
4207
|
-
*
|
|
4208
|
-
*
|
|
4209
|
-
* is over the bytes the sender hashed, and `JSON.parse` followed by
|
|
4210
|
-
* `JSON.stringify` reorders keys, drops insignificant whitespace and
|
|
4211
|
-
* re-escapes non-ASCII, any of which changes the digest. Read the raw body
|
|
4212
|
-
* before your framework's JSON middleware does.
|
|
3607
|
+
* The EXACT bytes of the request body, as received — not a parsed or
|
|
3608
|
+
* re-serialized object: `JSON.stringify` reorders keys and re-escapes
|
|
3609
|
+
* text, changing the digest. Read the raw body before your JSON middleware.
|
|
4213
3610
|
*/
|
|
4214
3611
|
body: string | Uint8Array;
|
|
4215
3612
|
/** The `X-LangWatch-Signature` header value, verbatim. */
|
|
4216
3613
|
header: string;
|
|
4217
3614
|
/**
|
|
4218
3615
|
* The signing secret, or every secret this receiver currently accepts.
|
|
4219
|
-
*
|
|
4220
|
-
*
|
|
4221
|
-
* either, so there is no window where deliveries are refused.
|
|
3616
|
+
* Pass both during a rotation and the delivery verifies under either, so
|
|
3617
|
+
* there is no window where deliveries are refused.
|
|
4222
3618
|
*/
|
|
4223
3619
|
secret: string | readonly string[];
|
|
4224
3620
|
/**
|
|
@@ -4233,70 +3629,23 @@ interface VerifyWebhookSignatureOptions {
|
|
|
4233
3629
|
nowSeconds?: number;
|
|
4234
3630
|
}
|
|
4235
3631
|
/**
|
|
4236
|
-
* Verify a webhook delivery,
|
|
4237
|
-
*
|
|
4238
|
-
*
|
|
4239
|
-
* app.post("/langwatch", express.raw({ type: "application/json" }), (req, res) => {
|
|
4240
|
-
* try {
|
|
4241
|
-
* verifyWebhookSignature({
|
|
4242
|
-
* body: req.body, // the raw Buffer, before JSON parsing
|
|
4243
|
-
* header: req.header("X-LangWatch-Signature") ?? "",
|
|
4244
|
-
* secret: [process.env.WEBHOOK_SECRET_NEW, process.env.WEBHOOK_SECRET_OLD],
|
|
4245
|
-
* });
|
|
4246
|
-
* } catch (error) {
|
|
4247
|
-
* return res.status(400).send((error as WebhookSignatureVerificationError).code);
|
|
4248
|
-
* }
|
|
4249
|
-
* // Trusted from here.
|
|
4250
|
-
* });
|
|
4251
|
-
* ```
|
|
4252
|
-
*
|
|
4253
|
-
* Throws rather than returning false so that a delivery cannot be trusted by
|
|
4254
|
-
* forgetting to check a return value. The thrown
|
|
4255
|
-
* {@link WebhookSignatureVerificationError} carries a
|
|
4256
|
-
* {@link WebhookSignatureFailureCode} saying which check failed.
|
|
4257
|
-
*
|
|
4258
|
-
* Checks run in a fixed order, so a delivery that is both stale and wrongly
|
|
4259
|
-
* signed reports the staleness: a header that did not parse has no
|
|
4260
|
-
* trustworthy timestamp to judge, and a timestamp outside the window makes
|
|
4261
|
-
* the digest moot.
|
|
4262
|
-
*
|
|
4263
|
-
* A missing or empty secret is a configuration mistake rather than a bad
|
|
4264
|
-
* delivery, and raises `TypeError`. Reporting it as a failed verification
|
|
4265
|
-
* would let a receiver that lost its secret quietly refuse every delivery as
|
|
4266
|
-
* if the sender were at fault.
|
|
3632
|
+
* Verify a webhook delivery, throwing (not returning false) so a check can't
|
|
3633
|
+
* be skipped by accident. A missing/empty secret throws a plain `TypeError`
|
|
3634
|
+
* instead of a verification failure, so it's never mistaken for sender fault.
|
|
4267
3635
|
*/
|
|
4268
3636
|
declare function verifyWebhookSignature(options: VerifyWebhookSignatureOptions): void;
|
|
4269
3637
|
|
|
4270
3638
|
/**
|
|
4271
|
-
* The one HTTP client every
|
|
4272
|
-
*
|
|
4273
|
-
*
|
|
4274
|
-
* redirect to https. The global `fetch` follows it on its own and, for a 301
|
|
4275
|
-
* or 302, turns the POST into a GET and drops the body, so the event is lost
|
|
4276
|
-
* without an error. This client sends with `redirect: "manual"` and applies a
|
|
4277
|
-
* rule per method to the 3xx it gets back.
|
|
4278
|
-
*
|
|
4279
|
-
* GET and HEAD follow a 301, 302, 303, 307 or 308 with the same method, up to
|
|
4280
|
-
* five hops. A hop that keeps the origin, or only upgrades http to https on
|
|
4281
|
-
* the same host and port, keeps every header; any other hop drops the
|
|
4282
|
-
* credential headers first. A hop from https to http and a hop without a
|
|
4283
|
-
* Location are refused.
|
|
4284
|
-
*
|
|
4285
|
-
* Every other method follows exactly one redirect, and only when the target is
|
|
4286
|
-
* the same URL with the scheme changed from http to https (same host, port,
|
|
4287
|
-
* path and query). The replay uses the same method, headers and body bytes.
|
|
4288
|
-
*
|
|
4289
|
-
* Every refused redirect throws `LangWatchRedirectError`.
|
|
4290
|
-
*
|
|
4291
|
-
* This module depends on the SDK logger only, so the CLI boot graph and the
|
|
4292
|
-
* `agent` entry can import it without pulling anything else in.
|
|
3639
|
+
* The one HTTP client every LangWatch API request goes through, with
|
|
3640
|
+
* `redirect: "manual"` since the global `fetch` turns a POST into a GET on
|
|
3641
|
+
* a redirect. GET/HEAD follow up to `MAX_FOLLOW_HOPS`; refusal throws.
|
|
4293
3642
|
*/
|
|
4294
3643
|
|
|
4295
3644
|
declare class LangWatchRedirectError extends Error {
|
|
4296
3645
|
readonly url: string;
|
|
4297
3646
|
readonly location: string | null;
|
|
4298
3647
|
readonly status: number;
|
|
4299
|
-
constructor({ url, location, status
|
|
3648
|
+
constructor({ url, location, status }: {
|
|
4300
3649
|
url: string;
|
|
4301
3650
|
location: string | null;
|
|
4302
3651
|
status: number;
|
|
@@ -4323,4 +3672,4 @@ declare const logger: {
|
|
|
4323
3672
|
NoOpLogger: typeof NoOpLogger;
|
|
4324
3673
|
};
|
|
4325
3674
|
|
|
4326
|
-
export { type ArchivedProject, type ArchivedTeam, type BatchCreateRecordsResponse, type BudgetOnBreach, type BudgetScopeKind, type BudgetWindow, ComparisonError, type ComparisonMetric, type ComparisonOptions, type ComparisonStatus, type ComparisonVerdict, type CreateDatasetOptions, type CreateEvaluatorBody, type CreateFromUploadResponse, type CreateGatewayBudgetInput, type CreateGatewayBudgetScope, type CreateLangWatchFetchOptions, type CreateProjectInput, type CreateVirtualKeyInput, type CreateWebhookEndpointInput, type Dataset, DatasetApiError, type DatasetColumnType, type DatasetEntry, DatasetError, type DatasetListItem, type DatasetMetadata, DatasetNotFoundError, DatasetPlanLimitError, type DatasetRecordResponse, DatasetValidationError, DatasetsFacade, type DeleteRecordsResponse, type EmittedEvent, type EmittedEventsPage, type EndUserCap, type EndUserSpend, type EvaluateOptions, type EvaluationCost, EvaluationError, type EvaluationResult, type EvaluationStatus, EvaluationsApiError, EvaluationsFacade, EvaluatorCallError, EvaluatorError, type EvaluatorField, EvaluatorNotFoundError, type EvaluatorResponse, EvaluatorsApiError, EvaluatorsApiService, Experiment, ExperimentApiError, ExperimentError, type
|
|
3675
|
+
export { type ArchivedProject, type ArchivedTeam, type BatchCreateRecordsResponse, type BudgetOnBreach, type BudgetScopeKind, type BudgetWindow, ComparisonError, type ComparisonMetric, type ComparisonOptions, type ComparisonStatus, type ComparisonVerdict, type CreateDatasetOptions, type CreateEvaluatorBody, type CreateFromUploadResponse, type CreateGatewayBudgetInput, type CreateGatewayBudgetScope, type CreateLangWatchFetchOptions, type CreateProjectInput, type CreateVirtualKeyInput, type CreateWebhookEndpointInput, type Dataset, DatasetApiError, type DatasetColumnType, type DatasetEntry, DatasetError, type DatasetListItem, type DatasetMetadata, DatasetNotFoundError, DatasetPlanLimitError, type DatasetRecordResponse, DatasetValidationError, DatasetsFacade, type DeleteRecordsResponse, type EmittedEvent, type EmittedEventsPage, type EndUserCap, type EndUserSpend, type EvaluateOptions, type EvaluationCost, EvaluationError, type EvaluationResult, type EvaluationStatus, EvaluationsApiError, EvaluationsFacade, EvaluatorCallError, EvaluatorError, type EvaluatorField, EvaluatorNotFoundError, type EvaluatorResponse, EvaluatorsApiError, EvaluatorsApiService, Experiment, ExperimentApiError, ExperimentError, type ExperimentEvaluateOptions, type ExperimentEvaluationResult, type ExperimentEvaluationStatus, ExperimentInitError, type ExperimentInitOptions, type ExperimentRowResult, type ExperimentRunWithResults, ExperimentsFacade, FetchPolicy, type GatewayBudget, type GatewayBudgetPage, GatewayBudgetsApiError, GatewayBudgetsApiService, type GetDatasetOptions, type GetPromptOptions, IDEMPOTENCY_KEY_HEADER, IDEMPOTENT_REPLAY_HEADER, type IdempotentCreateOptions, LangWatch, LangWatchApiError, type LangWatchFetch, LangWatchHandledError, LangWatchRedirectError, type ListDatasetsApiResponse, type ListDatasetsOptions, type ListRecordsApiResponse, type ListRecordsOptions, type ListTeamsResponse, type LogOptions, type MutationOptions, type PaginatedProjects, type PaginatedResponse, type Pagination, type Project, type ProjectWithServiceKey, ProjectsApiError, ProjectsApiService, type RunCallback, type RunContext, type RunOptions, type RunWithResultsOptions, type SpendEvent, type SpendEventStatus, SpendEventsApiError, SpendEventsApiService, type SpendEventsPage, type SpendFilterOptions, type SpendGroupBy, type SpendReplayResult, type SpendSummariesOptions, type SpendSummariesPage, type SpendSummaryRow, type SpendSummaryStatus, type TargetInfo, type TargetMetadata, TargetMetadataConflictError, type TargetType, type Team, type TeamMember, type TeamPagination, TeamsApiError, TeamsApiService, type UpdateDatasetOptions, type UpdateGatewayBudgetInput, type UpdateProjectInput, type UpdateVirtualKeyInput, type UpdateWebhookEndpointInput, type UploadResponse, type VerifyWebhookSignatureOptions, type VirtualKey, type VirtualKeyBudgetInput, type VirtualKeyPage, type VirtualKeyRoutingMode, type VirtualKeyScope, type VirtualKeyScopeType, type VirtualKeySpendSummary, type VirtualKeyWithSecret, VirtualKeysApiError, VirtualKeysApiService, WEBHOOK_DELIVERY_ID_HEADER, WEBHOOK_EVENT_ID_HEADER, WEBHOOK_SIGNATURE_DEFAULT_TOLERANCE_SECONDS, WEBHOOK_SIGNATURE_HEADER, type WebhookDeliveryPage, type WebhookDeliveryRecord, type WebhookEndpointHealth, type WebhookEndpointSummary, type WebhookEndpointWithSecret, type WebhookEventType, type WebhookSignatureFailureCode, WebhookSignatureVerificationError, type WebhookTestResult, WebhooksApiError, WebhooksApiService, createLangWatchFetch, isLangWatchHandledError, langwatchFetch, logger, verifyWebhookSignature };
|