scorecard-ai 1.1.0 → 2.0.0-alpha.1

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.
Files changed (98) hide show
  1. package/CHANGELOG.md +50 -0
  2. package/README.md +4 -5
  3. package/client.d.mts +13 -13
  4. package/client.d.mts.map +1 -1
  5. package/client.d.ts +13 -13
  6. package/client.d.ts.map +1 -1
  7. package/client.js +27 -25
  8. package/client.js.map +1 -1
  9. package/client.mjs +16 -14
  10. package/client.mjs.map +1 -1
  11. package/core/resource.d.mts +1 -1
  12. package/core/resource.d.mts.map +1 -1
  13. package/core/resource.d.ts +1 -1
  14. package/core/resource.d.ts.map +1 -1
  15. package/core/resource.js.map +1 -1
  16. package/core/resource.mjs.map +1 -1
  17. package/internal/headers.d.mts.map +1 -1
  18. package/internal/headers.d.ts.map +1 -1
  19. package/internal/headers.js +4 -4
  20. package/internal/headers.js.map +1 -1
  21. package/internal/headers.mjs +4 -4
  22. package/internal/headers.mjs.map +1 -1
  23. package/internal/request-options.d.mts +1 -0
  24. package/internal/request-options.d.mts.map +1 -1
  25. package/internal/request-options.d.ts +1 -0
  26. package/internal/request-options.d.ts.map +1 -1
  27. package/internal/request-options.js.map +1 -1
  28. package/internal/request-options.mjs.map +1 -1
  29. package/internal/uploads.js +1 -1
  30. package/internal/uploads.js.map +1 -1
  31. package/internal/uploads.mjs +1 -1
  32. package/internal/uploads.mjs.map +1 -1
  33. package/internal/utils/log.js +1 -1
  34. package/internal/utils/log.js.map +1 -1
  35. package/internal/utils/log.mjs +1 -1
  36. package/internal/utils/log.mjs.map +1 -1
  37. package/internal/utils/path.d.mts.map +1 -1
  38. package/internal/utils/path.d.ts.map +1 -1
  39. package/internal/utils/path.js.map +1 -1
  40. package/internal/utils/path.mjs +1 -1
  41. package/internal/utils/path.mjs.map +1 -1
  42. package/internal/utils/values.d.mts +2 -0
  43. package/internal/utils/values.d.mts.map +1 -1
  44. package/internal/utils/values.d.ts +2 -0
  45. package/internal/utils/values.d.ts.map +1 -1
  46. package/internal/utils/values.js +4 -1
  47. package/internal/utils/values.js.map +1 -1
  48. package/internal/utils/values.mjs +2 -0
  49. package/internal/utils/values.mjs.map +1 -1
  50. package/package.json +1 -1
  51. package/resources/index.d.mts +1 -1
  52. package/resources/index.d.mts.map +1 -1
  53. package/resources/index.d.ts +1 -1
  54. package/resources/index.d.ts.map +1 -1
  55. package/resources/systems/index.d.mts +2 -2
  56. package/resources/systems/index.d.mts.map +1 -1
  57. package/resources/systems/index.d.ts +2 -2
  58. package/resources/systems/index.d.ts.map +1 -1
  59. package/resources/systems/index.js.map +1 -1
  60. package/resources/systems/index.mjs +1 -1
  61. package/resources/systems/index.mjs.map +1 -1
  62. package/resources/systems/systems.d.mts +63 -125
  63. package/resources/systems/systems.d.mts.map +1 -1
  64. package/resources/systems/systems.d.ts +63 -125
  65. package/resources/systems/systems.d.ts.map +1 -1
  66. package/resources/systems/systems.js +21 -74
  67. package/resources/systems/systems.js.map +1 -1
  68. package/resources/systems/systems.mjs +22 -75
  69. package/resources/systems/systems.mjs.map +1 -1
  70. package/resources/systems/versions.d.mts +23 -74
  71. package/resources/systems/versions.d.mts.map +1 -1
  72. package/resources/systems/versions.d.ts +23 -74
  73. package/resources/systems/versions.d.ts.map +1 -1
  74. package/resources/systems/versions.js +20 -54
  75. package/resources/systems/versions.js.map +1 -1
  76. package/resources/systems/versions.mjs +20 -54
  77. package/resources/systems/versions.mjs.map +1 -1
  78. package/src/client.ts +39 -27
  79. package/src/core/resource.ts +1 -1
  80. package/src/internal/headers.ts +5 -5
  81. package/src/internal/request-options.ts +1 -0
  82. package/src/internal/uploads.ts +1 -1
  83. package/src/internal/utils/log.ts +1 -1
  84. package/src/internal/utils/path.ts +1 -1
  85. package/src/internal/utils/values.ts +3 -0
  86. package/src/resources/index.ts +1 -1
  87. package/src/resources/systems/index.ts +2 -8
  88. package/src/resources/systems/systems.ts +68 -141
  89. package/src/resources/systems/versions.ts +25 -95
  90. package/src/version.ts +1 -1
  91. package/version.d.mts +1 -1
  92. package/version.d.mts.map +1 -1
  93. package/version.d.ts +1 -1
  94. package/version.d.ts.map +1 -1
  95. package/version.js +1 -1
  96. package/version.js.map +1 -1
  97. package/version.mjs +1 -1
  98. package/version.mjs.map +1 -1
package/src/client.ts CHANGED
@@ -5,7 +5,6 @@ import type { HTTPMethod, PromiseOrValue, MergedRequestInit, FinalizedRequestIni
5
5
  import { uuid4 } from './internal/utils/uuid';
6
6
  import { validatePositiveInteger, isAbsoluteURL, safeJSON } from './internal/utils/values';
7
7
  import { sleep } from './internal/utils/sleep';
8
- import { type Logger, type LogLevel, parseLogLevel } from './internal/utils/log';
9
8
  export type { Logger, LogLevel } from './internal/utils/log';
10
9
  import { castToError, isAbortError } from './internal/errors';
11
10
  import type { APIResponseProps } from './internal/parse';
@@ -19,9 +18,6 @@ import { AbstractPage, type PaginatedResponseParams, PaginatedResponseResponse }
19
18
  import * as Uploads from './core/uploads';
20
19
  import * as API from './resources/index';
21
20
  import { APIPromise } from './core/api-promise';
22
- import { type Fetch } from './internal/builtin-types';
23
- import { HeadersLike, NullableHeaders, buildHeaders } from './internal/headers';
24
- import { FinalRequestOptions, RequestOptions } from './internal/request-options';
25
21
  import { Metric, MetricCreateParams, MetricUpdateParams, Metrics } from './resources/metrics';
26
22
  import {
27
23
  Project,
@@ -30,7 +26,7 @@ import {
30
26
  Projects,
31
27
  ProjectsPaginatedResponse,
32
28
  } from './resources/projects';
33
- import { Record as RecordsAPIRecord, RecordCreateParams, Records } from './resources/records';
29
+ import { Record, RecordCreateParams, Records } from './resources/records';
34
30
  import { Run, RunCreateParams, Runs } from './resources/runs';
35
31
  import { Score, ScoreUpsertParams, Scores } from './resources/scores';
36
32
  import {
@@ -53,18 +49,27 @@ import {
53
49
  Testsets,
54
50
  TestsetsPaginatedResponse,
55
51
  } from './resources/testsets';
56
- import { readEnv } from './internal/utils/env';
57
- import { formatRequestDetails, loggerFor } from './internal/utils/log';
58
- import { isEmptyObj } from './internal/utils/values';
59
52
  import {
60
53
  System,
61
- SystemCreateParams,
62
54
  SystemDeleteResponse,
63
55
  SystemListParams,
64
56
  SystemUpdateParams,
57
+ SystemUpsertParams,
65
58
  Systems,
66
59
  SystemsPaginatedResponse,
67
60
  } from './resources/systems/systems';
61
+ import { type Fetch, type Record as BuiltinRecord } from './internal/builtin-types';
62
+ import { HeadersLike, NullableHeaders, buildHeaders } from './internal/headers';
63
+ import { FinalRequestOptions, RequestOptions } from './internal/request-options';
64
+ import { readEnv } from './internal/utils/env';
65
+ import {
66
+ type LogLevel,
67
+ type Logger,
68
+ formatRequestDetails,
69
+ loggerFor,
70
+ parseLogLevel,
71
+ } from './internal/utils/log';
72
+ import { isEmptyObj } from './internal/utils/values';
68
73
 
69
74
  const environments = {
70
75
  production: 'https://api2.scorecard.io/api/v2',
@@ -151,7 +156,7 @@ export interface ClientOptions {
151
156
  * These can be removed in individual requests by explicitly setting the
152
157
  * param to `undefined` in request options.
153
158
  */
154
- defaultQuery?: Record<string, string | undefined> | undefined;
159
+ defaultQuery?: BuiltinRecord<string, string | undefined> | undefined;
155
160
 
156
161
  /**
157
162
  * Set the log level.
@@ -198,7 +203,7 @@ export class Scorecard {
198
203
  * @param {Fetch} [opts.fetch] - Specify a custom `fetch` function implementation.
199
204
  * @param {number} [opts.maxRetries=2] - The maximum number of times the client will retry a request.
200
205
  * @param {HeadersLike} opts.defaultHeaders - Default headers to include with every request to the API.
201
- * @param {Record<string, string | undefined>} opts.defaultQuery - Default query parameters to include with every request to the API.
206
+ * @param {BuiltinRecord<string, string | undefined>} opts.defaultQuery - Default query parameters to include with every request to the API.
202
207
  */
203
208
  constructor({
204
209
  baseURL = readEnv('SCORECARD_BASE_URL'),
@@ -210,8 +215,6 @@ export class Scorecard {
210
215
  "The SCORECARD_API_KEY environment variable is missing or empty; either provide it, or instantiate the Scorecard client with an apiKey option, like new Scorecard({ apiKey: 'My API Key' }).",
211
216
  );
212
217
  }
213
- // Support both API keys (which start with 'ak_') and legacy JWT bearer tokens
214
- apiKey = !apiKey || apiKey.startsWith('ak_') ? apiKey : `Bearer ${apiKey}`;
215
218
 
216
219
  const options: ClientOptions = {
217
220
  apiKey,
@@ -259,13 +262,21 @@ export class Scorecard {
259
262
  timeout: this.timeout,
260
263
  logger: this.logger,
261
264
  logLevel: this.logLevel,
265
+ fetch: this.fetch,
262
266
  fetchOptions: this.fetchOptions,
263
267
  apiKey: this.apiKey,
264
268
  ...options,
265
269
  });
266
270
  }
267
271
 
268
- protected defaultQuery(): Record<string, string | undefined> | undefined {
272
+ /**
273
+ * Check whether the base URL is set to its default.
274
+ */
275
+ #baseURLOverridden(): boolean {
276
+ return this.baseURL !== environments[this._options.environment || 'production'];
277
+ }
278
+
279
+ protected defaultQuery(): BuiltinRecord<string, string | undefined> | undefined {
269
280
  return this._options.defaultQuery;
270
281
  }
271
282
 
@@ -274,13 +285,13 @@ export class Scorecard {
274
285
  }
275
286
 
276
287
  protected authHeaders(opts: FinalRequestOptions): NullableHeaders | undefined {
277
- return buildHeaders([{ Authorization: this.apiKey }]);
288
+ return buildHeaders([{ Authorization: `Bearer ${this.apiKey}` }]);
278
289
  }
279
290
 
280
291
  /**
281
292
  * Basic re-implementation of `qs.stringify` for primitive types.
282
293
  */
283
- protected stringifyQuery(query: Record<string, unknown>): string {
294
+ protected stringifyQuery(query: BuiltinRecord<string, unknown>): string {
284
295
  return Object.entries(query)
285
296
  .filter(([_, value]) => typeof value !== 'undefined')
286
297
  .map(([key, value]) => {
@@ -314,11 +325,16 @@ export class Scorecard {
314
325
  return Errors.APIError.generate(status, error, message, headers);
315
326
  }
316
327
 
317
- buildURL(path: string, query: Record<string, unknown> | null | undefined): string {
328
+ buildURL(
329
+ path: string,
330
+ query: BuiltinRecord<string, unknown> | null | undefined,
331
+ defaultBaseURL?: string | undefined,
332
+ ): string {
333
+ const baseURL = (!this.#baseURLOverridden() && defaultBaseURL) || this.baseURL;
318
334
  const url =
319
335
  isAbsoluteURL(path) ?
320
336
  new URL(path)
321
- : new URL(this.baseURL + (this.baseURL.endsWith('/') && path.startsWith('/') ? path.slice(1) : path));
337
+ : new URL(baseURL + (baseURL.endsWith('/') && path.startsWith('/') ? path.slice(1) : path));
322
338
 
323
339
  const defaultQuery = this.defaultQuery();
324
340
  if (!isEmptyObj(defaultQuery)) {
@@ -326,7 +342,7 @@ export class Scorecard {
326
342
  }
327
343
 
328
344
  if (typeof query === 'object' && query && !Array.isArray(query)) {
329
- url.search = this.stringifyQuery(query as Record<string, unknown>);
345
+ url.search = this.stringifyQuery(query as BuiltinRecord<string, unknown>);
330
346
  }
331
347
 
332
348
  return url.toString();
@@ -678,9 +694,9 @@ export class Scorecard {
678
694
  { retryCount = 0 }: { retryCount?: number } = {},
679
695
  ): { req: FinalizedRequestInit; url: string; timeout: number } {
680
696
  const options = { ...inputOptions };
681
- const { method, path, query } = options;
697
+ const { method, path, query, defaultBaseURL } = options;
682
698
 
683
- const url = this.buildURL(path!, query as Record<string, unknown>);
699
+ const url = this.buildURL(path!, query as BuiltinRecord<string, unknown>, defaultBaseURL);
684
700
  if ('timeout' in options) validatePositiveInteger('timeout', options.timeout);
685
701
  options.timeout = options.timeout ?? this.timeout;
686
702
  const { bodyHeaders, body } = this.buildBody({ options });
@@ -858,11 +874,7 @@ export declare namespace Scorecard {
858
874
  type MetricUpdateParams as MetricUpdateParams,
859
875
  };
860
876
 
861
- export {
862
- Records as Records,
863
- type RecordsAPIRecord as Record,
864
- type RecordCreateParams as RecordCreateParams,
865
- };
877
+ export { Records as Records, type Record as Record, type RecordCreateParams as RecordCreateParams };
866
878
 
867
879
  export { Scores as Scores, type Score as Score, type ScoreUpsertParams as ScoreUpsertParams };
868
880
 
@@ -871,9 +883,9 @@ export declare namespace Scorecard {
871
883
  type System as System,
872
884
  type SystemDeleteResponse as SystemDeleteResponse,
873
885
  type SystemsPaginatedResponse as SystemsPaginatedResponse,
874
- type SystemCreateParams as SystemCreateParams,
875
886
  type SystemUpdateParams as SystemUpdateParams,
876
887
  type SystemListParams as SystemListParams,
888
+ type SystemUpsertParams as SystemUpsertParams,
877
889
  };
878
890
 
879
891
  export type APIError = API.APIError;
@@ -2,7 +2,7 @@
2
2
 
3
3
  import type { Scorecard } from '../client';
4
4
 
5
- export class APIResource {
5
+ export abstract class APIResource {
6
6
  protected _client: Scorecard;
7
7
 
8
8
  constructor(client: Scorecard) {
@@ -1,5 +1,7 @@
1
1
  // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
2
2
 
3
+ import { isReadonlyArray } from './utils/values';
4
+
3
5
  type HeaderValue = string | undefined | null;
4
6
  export type HeadersLike =
5
7
  | Headers
@@ -9,7 +11,7 @@ export type HeadersLike =
9
11
  | null
10
12
  | NullableHeaders;
11
13
 
12
- const brand_privateNullableHeaders = Symbol('brand.privateNullableHeaders');
14
+ const brand_privateNullableHeaders = /* @__PURE__ */ Symbol('brand.privateNullableHeaders');
13
15
 
14
16
  /**
15
17
  * @internal
@@ -25,8 +27,6 @@ export type NullableHeaders = {
25
27
  nulls: Set<string>;
26
28
  };
27
29
 
28
- const isArray = Array.isArray as (val: unknown) => val is readonly unknown[];
29
-
30
30
  function* iterateHeaders(headers: HeadersLike): IterableIterator<readonly [string, string | null]> {
31
31
  if (!headers) return;
32
32
 
@@ -43,7 +43,7 @@ function* iterateHeaders(headers: HeadersLike): IterableIterator<readonly [strin
43
43
  let iter: Iterable<readonly (HeaderValue | readonly HeaderValue[])[]>;
44
44
  if (headers instanceof Headers) {
45
45
  iter = headers.entries();
46
- } else if (isArray(headers)) {
46
+ } else if (isReadonlyArray(headers)) {
47
47
  iter = headers;
48
48
  } else {
49
49
  shouldClear = true;
@@ -52,7 +52,7 @@ function* iterateHeaders(headers: HeadersLike): IterableIterator<readonly [strin
52
52
  for (let row of iter) {
53
53
  const name = row[0];
54
54
  if (typeof name !== 'string') throw new TypeError('expected header name to be a string');
55
- const values = isArray(row[1]) ? row[1] : [row[1]];
55
+ const values = isReadonlyArray(row[1]) ? row[1] : [row[1]];
56
56
  let didClear = false;
57
57
  for (const value of values) {
58
58
  if (value === undefined) continue;
@@ -20,6 +20,7 @@ export type RequestOptions = {
20
20
  fetchOptions?: MergedRequestInit;
21
21
  signal?: AbortSignal | undefined | null;
22
22
  idempotencyKey?: string;
23
+ defaultBaseURL?: string | undefined;
23
24
 
24
25
  __binaryResponse?: boolean | undefined;
25
26
  };
@@ -90,7 +90,7 @@ export const multipartFormRequestOptions = async (
90
90
  return { ...opts, body: await createForm(opts.body, fetch) };
91
91
  };
92
92
 
93
- const supportsFormDataMap = new WeakMap<Fetch, Promise<boolean>>();
93
+ const supportsFormDataMap = /** @__PURE__ */ new WeakMap<Fetch, Promise<boolean>>();
94
94
 
95
95
  /**
96
96
  * node-fetch doesn't support the global FormData object in recent node versions. Instead of sending
@@ -58,7 +58,7 @@ const noopLogger = {
58
58
  debug: noop,
59
59
  };
60
60
 
61
- let cachedLoggers = new WeakMap<Logger, [LogLevel, Logger]>();
61
+ let cachedLoggers = /** @__PURE__ */ new WeakMap<Logger, [LogLevel, Logger]>();
62
62
 
63
63
  export function loggerFor(client: Scorecard): Logger {
64
64
  const logger = client.logger;
@@ -62,4 +62,4 @@ export const createPathTagFunction = (pathEncoder = encodeURIPath) =>
62
62
  /**
63
63
  * URI-encodes path params and ensures no unsafe /./ or /../ path segments are introduced.
64
64
  */
65
- export const path = createPathTagFunction(encodeURIPath);
65
+ export const path = /* @__PURE__ */ createPathTagFunction(encodeURIPath);
@@ -9,6 +9,9 @@ export const isAbsoluteURL = (url: string): boolean => {
9
9
  return startsWithSchemeRegexp.test(url);
10
10
  };
11
11
 
12
+ export let isArray = (val: unknown): val is unknown[] => ((isArray = Array.isArray), isArray(val));
13
+ export let isReadonlyArray = isArray as (val: unknown) => val is readonly unknown[];
14
+
12
15
  /** Returns an object if the given value isn't an object, otherwise returns as-is */
13
16
  export function maybeObj(x: unknown): object {
14
17
  if (typeof x !== 'object') {
@@ -16,9 +16,9 @@ export {
16
16
  Systems,
17
17
  type System,
18
18
  type SystemDeleteResponse,
19
- type SystemCreateParams,
20
19
  type SystemUpdateParams,
21
20
  type SystemListParams,
21
+ type SystemUpsertParams,
22
22
  type SystemsPaginatedResponse,
23
23
  } from './systems/systems';
24
24
  export {
@@ -4,15 +4,9 @@ export {
4
4
  Systems,
5
5
  type System,
6
6
  type SystemDeleteResponse,
7
- type SystemCreateParams,
8
7
  type SystemUpdateParams,
9
8
  type SystemListParams,
9
+ type SystemUpsertParams,
10
10
  type SystemsPaginatedResponse,
11
11
  } from './systems';
12
- export {
13
- Versions,
14
- type SystemVersion,
15
- type VersionCreateParams,
16
- type VersionListParams,
17
- type SystemVersionsPaginatedResponse,
18
- } from './versions';
12
+ export { Versions, type SystemVersion, type VersionUpsertParams } from './versions';
@@ -2,13 +2,7 @@
2
2
 
3
3
  import { APIResource } from '../../core/resource';
4
4
  import * as VersionsAPI from './versions';
5
- import {
6
- SystemVersion,
7
- SystemVersionsPaginatedResponse,
8
- VersionCreateParams,
9
- VersionListParams,
10
- Versions,
11
- } from './versions';
5
+ import { SystemVersion, VersionUpsertParams, Versions } from './versions';
12
6
  import { APIPromise } from '../../core/api-promise';
13
7
  import { PagePromise, PaginatedResponse, type PaginatedResponseParams } from '../../core/pagination';
14
8
  import { RequestOptions } from '../../internal/request-options';
@@ -18,87 +12,17 @@ export class Systems extends APIResource {
18
12
  versions: VersionsAPI.Versions = new VersionsAPI.Versions(this._client);
19
13
 
20
14
  /**
21
- * Create a new system definition that specifies the interface contracts for a
22
- * component you want to evaluate.
23
- *
24
- * A system acts as a template that defines three key contracts through JSON
25
- * Schemas:
26
- *
27
- * 1. Input Schema: What data your system accepts (e.g., user queries, context
28
- * documents)
29
- * 2. Output Schema: What data your system produces (e.g., responses, confidence
30
- * scores)
31
- * 3. Config Schema: What parameters can be adjusted (e.g., model selection,
32
- * temperature)
33
- *
34
- * This separation lets you evaluate any system as a black box, focusing on its
35
- * interface rather than implementation details.
36
- *
37
- * @example
38
- * ```ts
39
- * const system = await client.systems.create('314', {
40
- * configSchema: {
41
- * type: 'object',
42
- * properties: {
43
- * temperature: { type: 'number' },
44
- * maxTokens: { type: 'integer' },
45
- * model: { type: 'string', enum: ['gpt-4', 'gpt-4-turbo'] },
46
- * },
47
- * required: ['model'],
48
- * },
49
- * description: 'Production chatbot powered by GPT-4',
50
- * inputSchema: {
51
- * type: 'object',
52
- * properties: {
53
- * messages: {
54
- * type: 'array',
55
- * items: {
56
- * type: 'object',
57
- * properties: {
58
- * role: { type: 'string', enum: ['system', 'user', 'assistant'] },
59
- * content: { type: 'string' },
60
- * },
61
- * required: ['role', 'content'],
62
- * },
63
- * },
64
- * },
65
- * required: ['messages'],
66
- * },
67
- * name: 'GPT-4 Chatbot',
68
- * outputSchema: {
69
- * type: 'object',
70
- * properties: { response: { type: 'string' } },
71
- * required: ['response'],
72
- * },
73
- * });
74
- * ```
75
- */
76
- create(projectID: string, body: SystemCreateParams, options?: RequestOptions): APIPromise<System> {
77
- return this._client.post(path`/projects/${projectID}/systems`, { body, ...options });
78
- }
79
-
80
- /**
81
- * Update an existing system definition. Only the fields provided in the request
82
- * body will be updated. If a field is provided, the new content will replace the
83
- * existing content. If a field is not provided, the existing content will remain
84
- * unchanged.
85
- *
86
- * When updating schemas:
87
- *
88
- * - The system will accept your changes regardless of compatibility with existing
89
- * configurations
90
- * - Schema updates won't invalidate existing evaluations or configurations
91
- * - For significant redesigns, creating a new system definition provides a cleaner
92
- * separation
15
+ * Update an existing system. Only the fields provided in the request body will be
16
+ * updated. If a field is provided, the new content will replace the existing
17
+ * content. If a field is not provided, the existing content will remain unchanged.
93
18
  *
94
19
  * @example
95
20
  * ```ts
96
21
  * const system = await client.systems.update(
97
22
  * '12345678-0a8b-4f66-b6f3-2ddcfa097257',
98
23
  * {
99
- * description:
100
- * 'Updated production chatbot powered by GPT-4 Turbo',
101
- * name: 'GPT-4 Turbo Chatbot',
24
+ * productionVersionId:
25
+ * '87654321-4d3b-4ae4-8c7a-4b6e2a19ccf3',
102
26
  * },
103
27
  * );
104
28
  * ```
@@ -161,23 +85,29 @@ export class Systems extends APIResource {
161
85
  get(systemID: string, options?: RequestOptions): APIPromise<System> {
162
86
  return this._client.get(path`/systems/${systemID}`, options);
163
87
  }
88
+
89
+ /**
90
+ * Create a new system. If one with the same name in the project exists, it updates
91
+ * it instead.
92
+ *
93
+ * @example
94
+ * ```ts
95
+ * const system = await client.systems.upsert('314', {
96
+ * config: { temperature: 0.1, maxTokens: 1024 },
97
+ * description: 'Production chatbot powered by GPT-4',
98
+ * name: 'GPT-4 Chatbot',
99
+ * });
100
+ * ```
101
+ */
102
+ upsert(projectID: string, body: SystemUpsertParams, options?: RequestOptions): APIPromise<System> {
103
+ return this._client.post(path`/projects/${projectID}/systems`, { body, ...options });
104
+ }
164
105
  }
165
106
 
166
107
  export type SystemsPaginatedResponse = PaginatedResponse<System>;
167
108
 
168
109
  /**
169
- * A System Under Test (SUT) defines the interface to a component or service you
170
- * want to evaluate.
171
- *
172
- * It specifies three contracts through schemas:
173
- *
174
- * - inputSchema: The structure of data the system accepts.
175
- * - outputSchema: The structure of data the system produces.
176
- * - configSchema: The parameters that modify system behavior.
177
- *
178
- * This abstraction lets you evaluate any system as a black box, focusing on its
179
- * interface rather than implementation details. It's particularly useful for
180
- * systems with variable outputs or complex internal state.
110
+ * A System Under Test (SUT).
181
111
  *
182
112
  * Systems are templates - to run evaluations, pair them with a SystemVersion that
183
113
  * provides specific parameter values.
@@ -188,30 +118,48 @@ export interface System {
188
118
  */
189
119
  id: string;
190
120
 
191
- /**
192
- * The schema of the system's configuration.
193
- */
194
- configSchema: Record<string, unknown>;
195
-
196
121
  /**
197
122
  * The description of the system.
198
123
  */
199
124
  description: string;
200
125
 
201
126
  /**
202
- * The schema of the system's inputs.
127
+ * The name of the system. Unique within the project.
203
128
  */
204
- inputSchema: Record<string, unknown>;
129
+ name: string;
205
130
 
206
131
  /**
207
- * The name of the system.
132
+ * The production version of the system.
208
133
  */
209
- name: string;
134
+ productionVersion: VersionsAPI.SystemVersion;
210
135
 
211
136
  /**
212
- * The schema of the system's outputs.
137
+ * The versions of the system.
213
138
  */
214
- outputSchema: Record<string, unknown>;
139
+ versions: Array<System.Version>;
140
+ }
141
+
142
+ export namespace System {
143
+ /**
144
+ * A SystemVersion defines the specific settings for a System Under Test.
145
+ *
146
+ * System versions contain parameter values that determine system behavior during
147
+ * evaluation. They are immutable snapshots - once created, they never change.
148
+ *
149
+ * When running evaluations, you reference a specific systemVersionId to establish
150
+ * which system version to test.
151
+ */
152
+ export interface Version {
153
+ /**
154
+ * The ID of the system version.
155
+ */
156
+ id: string;
157
+
158
+ /**
159
+ * The name of the system version.
160
+ */
161
+ name: string;
162
+ }
215
163
  }
216
164
 
217
165
  export interface SystemDeleteResponse {
@@ -221,38 +169,30 @@ export interface SystemDeleteResponse {
221
169
  success: boolean;
222
170
  }
223
171
 
224
- export interface SystemCreateParams {
225
- /**
226
- * The schema of the system's configuration.
227
- */
228
- configSchema: Record<string, unknown>;
229
-
172
+ export interface SystemUpdateParams {
230
173
  /**
231
174
  * The description of the system.
232
175
  */
233
- description: string;
234
-
235
- /**
236
- * The schema of the system's inputs.
237
- */
238
- inputSchema: Record<string, unknown>;
176
+ description?: string;
239
177
 
240
178
  /**
241
- * The name of the system.
179
+ * The name of the system. Unique within the project.
242
180
  */
243
- name: string;
181
+ name?: string;
244
182
 
245
183
  /**
246
- * The schema of the system's outputs.
184
+ * The ID of the production version of the system.
247
185
  */
248
- outputSchema: Record<string, unknown>;
186
+ productionVersionId?: string;
249
187
  }
250
188
 
251
- export interface SystemUpdateParams {
189
+ export interface SystemListParams extends PaginatedResponseParams {}
190
+
191
+ export interface SystemUpsertParams {
252
192
  /**
253
- * The schema of the system's configuration.
193
+ * The configuration of the system.
254
194
  */
255
- configSchema?: Record<string, unknown>;
195
+ config: Record<string, unknown>;
256
196
 
257
197
  /**
258
198
  * The description of the system.
@@ -260,23 +200,12 @@ export interface SystemUpdateParams {
260
200
  description?: string;
261
201
 
262
202
  /**
263
- * The schema of the system's inputs.
264
- */
265
- inputSchema?: Record<string, unknown>;
266
-
267
- /**
268
- * The name of the system.
203
+ * The name of the system. Should be unique within the project. Default is "Default
204
+ * system"
269
205
  */
270
206
  name?: string;
271
-
272
- /**
273
- * The schema of the system's outputs.
274
- */
275
- outputSchema?: Record<string, unknown>;
276
207
  }
277
208
 
278
- export interface SystemListParams extends PaginatedResponseParams {}
279
-
280
209
  Systems.Versions = Versions;
281
210
 
282
211
  export declare namespace Systems {
@@ -284,16 +213,14 @@ export declare namespace Systems {
284
213
  type System as System,
285
214
  type SystemDeleteResponse as SystemDeleteResponse,
286
215
  type SystemsPaginatedResponse as SystemsPaginatedResponse,
287
- type SystemCreateParams as SystemCreateParams,
288
216
  type SystemUpdateParams as SystemUpdateParams,
289
217
  type SystemListParams as SystemListParams,
218
+ type SystemUpsertParams as SystemUpsertParams,
290
219
  };
291
220
 
292
221
  export {
293
222
  Versions as Versions,
294
223
  type SystemVersion as SystemVersion,
295
- type SystemVersionsPaginatedResponse as SystemVersionsPaginatedResponse,
296
- type VersionCreateParams as VersionCreateParams,
297
- type VersionListParams as VersionListParams,
224
+ type VersionUpsertParams as VersionUpsertParams,
298
225
  };
299
226
  }