@runtypelabs/sdk 5.9.0 → 6.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -1151,6 +1151,7 @@ var FlowBuilder = class {
1151
1151
  markdownIfAvailable: config.markdownIfAvailable,
1152
1152
  fetchMethod: config.fetchMethod === "http" ? "standard" : config.fetchMethod,
1153
1153
  firecrawl: config.firecrawl,
1154
+ massive: config.massive,
1154
1155
  outputVariable: config.outputVariable,
1155
1156
  errorHandling: config.errorHandling,
1156
1157
  defaultValue: config.defaultValue,
@@ -1286,7 +1287,10 @@ var FlowBuilder = class {
1286
1287
  "send-stream",
1287
1288
  config.name,
1288
1289
  {
1289
- message: config.message
1290
+ message: config.message,
1291
+ outputVariable: config.outputVariable,
1292
+ errorHandling: config.errorHandling,
1293
+ defaultValue: config.defaultValue
1290
1294
  },
1291
1295
  config.enabled,
1292
1296
  config.when
@@ -1311,7 +1315,6 @@ var FlowBuilder = class {
1311
1315
  fieldsToExclude: config.fieldsToExclude,
1312
1316
  availableFields: config.availableFields,
1313
1317
  outputVariable: config.outputVariable,
1314
- fields: config.fields,
1315
1318
  includeMetadata: config.includeMetadata,
1316
1319
  streamOutput: config.streamOutput
1317
1320
  },
@@ -1404,7 +1407,6 @@ var FlowBuilder = class {
1404
1407
  vectorStore: config.vectorStore,
1405
1408
  weaviateConfig: config.weaviateConfig,
1406
1409
  vectorizeConfig: config.vectorizeConfig,
1407
- pineconeConfig: config.pineconeConfig,
1408
1410
  limit: config.limit,
1409
1411
  threshold: config.threshold,
1410
1412
  metadataFilters: config.metadataFilters,
@@ -1433,7 +1435,6 @@ var FlowBuilder = class {
1433
1435
  recordType: config.recordType,
1434
1436
  recordName: config.recordName,
1435
1437
  textField: config.textField,
1436
- storeInRecord: config.storeInRecord,
1437
1438
  embeddingModel: config.embeddingModel,
1438
1439
  maxLength: config.maxLength,
1439
1440
  inputMode: config.inputMode,
@@ -1441,7 +1442,6 @@ var FlowBuilder = class {
1441
1442
  itemAlias: config.itemAlias,
1442
1443
  textTemplate: config.textTemplate,
1443
1444
  batchSize: config.batchSize,
1444
- vectorStore: config.vectorStore,
1445
1445
  outputVariable: config.outputVariable,
1446
1446
  streamOutput: config.streamOutput
1447
1447
  },
@@ -1490,51 +1490,6 @@ var FlowBuilder = class {
1490
1490
  );
1491
1491
  return this;
1492
1492
  }
1493
- /**
1494
- * Add a send text step
1495
- */
1496
- sendText(config) {
1497
- this.addStep(
1498
- "send-text",
1499
- config.name,
1500
- {
1501
- to: config.to,
1502
- from: config.from,
1503
- message: config.message,
1504
- outputVariable: config.outputVariable,
1505
- errorHandling: config.errorHandling,
1506
- streamOutput: config.streamOutput
1507
- },
1508
- config.enabled,
1509
- config.when
1510
- );
1511
- return this;
1512
- }
1513
- /**
1514
- * Add a fetch GitHub step
1515
- */
1516
- fetchGitHub(config) {
1517
- this.addStep(
1518
- "fetch-github",
1519
- config.name,
1520
- {
1521
- repository: config.repository,
1522
- branch: config.branch,
1523
- path: config.path,
1524
- token: config.token,
1525
- outputVariable: config.outputVariable,
1526
- contentType: config.contentType,
1527
- includePatterns: config.includePatterns,
1528
- excludePatterns: config.excludePatterns,
1529
- compress: config.compress,
1530
- style: config.style,
1531
- streamOutput: config.streamOutput
1532
- },
1533
- config.enabled,
1534
- config.when
1535
- );
1536
- return this;
1537
- }
1538
1493
  /** Add an api-call step. */
1539
1494
  apiCall(config) {
1540
1495
  return this.addRawStep("api-call", config);
@@ -1938,6 +1893,31 @@ function resolveBatchExecutionId(pausedTools) {
1938
1893
  return "";
1939
1894
  }
1940
1895
 
1896
+ // src/content-hash.ts
1897
+ function isPlainObject(value) {
1898
+ return value !== null && typeof value === "object" && !Array.isArray(value);
1899
+ }
1900
+ function normalizeValue(value) {
1901
+ if (Array.isArray(value)) {
1902
+ return value.map((item) => normalizeValue(item));
1903
+ }
1904
+ if (isPlainObject(value)) {
1905
+ const normalized = {};
1906
+ for (const key of Object.keys(value).sort()) {
1907
+ const entry = value[key];
1908
+ if (entry === void 0 || entry === null) continue;
1909
+ normalized[key] = normalizeValue(entry);
1910
+ }
1911
+ return normalized;
1912
+ }
1913
+ return value;
1914
+ }
1915
+ async function sha256Hex(serialized) {
1916
+ const encoded = new TextEncoder().encode(serialized);
1917
+ const hashBuffer = await crypto.subtle.digest("SHA-256", encoded);
1918
+ return Array.from(new Uint8Array(hashBuffer)).map((b) => b.toString(16).padStart(2, "0")).join("");
1919
+ }
1920
+
1941
1921
  // src/evals-ensure.ts
1942
1922
  var CHECK_GRADER_KINDS = /* @__PURE__ */ new Set([
1943
1923
  "contains",
@@ -2153,12 +2133,11 @@ var DEFINE_EVAL_TOP_LEVEL_KEYS = /* @__PURE__ */ new Set([
2153
2133
  "target",
2154
2134
  "graders",
2155
2135
  "cases",
2156
- "virtual"
2136
+ "virtual",
2137
+ "recordedToolMode",
2138
+ "recordedToolUnmatchedPolicy"
2157
2139
  ]);
2158
2140
  var DEFINE_EVAL_CASE_KEYS = /* @__PURE__ */ new Set(["name", "input", "expected", "expect"]);
2159
- function isPlainObject(value) {
2160
- return value !== null && typeof value === "object" && !Array.isArray(value);
2161
- }
2162
2141
  function normalizeTarget(target) {
2163
2142
  if (!isPlainObject(target)) {
2164
2143
  throw new Error('defineEval requires a "target" object: { flow: name } or { agent: name }');
@@ -2225,9 +2204,15 @@ function defineEval(input) {
2225
2204
  const unknownKeys = Object.keys(input).filter((k) => !DEFINE_EVAL_TOP_LEVEL_KEYS.has(k));
2226
2205
  if (unknownKeys.length > 0) {
2227
2206
  throw new Error(
2228
- `defineEval: unknown field(s): ${unknownKeys.join(", ")}. Allowed fields are target, graders, cases, virtual.`
2207
+ `defineEval: unknown field(s): ${unknownKeys.join(", ")}. Allowed fields are target, graders, cases, virtual, recordedToolMode, recordedToolUnmatchedPolicy.`
2229
2208
  );
2230
2209
  }
2210
+ if (input.recordedToolMode !== void 0 && input.recordedToolMode !== "next_step" && input.recordedToolMode !== "continue") {
2211
+ throw new Error('defineEval "recordedToolMode" must be "next_step" or "continue"');
2212
+ }
2213
+ if (input.recordedToolUnmatchedPolicy !== void 0 && input.recordedToolUnmatchedPolicy !== "fail" && input.recordedToolUnmatchedPolicy !== "stub") {
2214
+ throw new Error('defineEval "recordedToolUnmatchedPolicy" must be "fail" or "stub"');
2215
+ }
2231
2216
  const target = normalizeTarget(input.target);
2232
2217
  if (input.name !== void 0 && (typeof input.name !== "string" || input.name.length === 0)) {
2233
2218
  throw new Error('defineEval "name" must be a non-empty string when provided');
@@ -2276,7 +2261,14 @@ function defineEval(input) {
2276
2261
  expect
2277
2262
  };
2278
2263
  });
2279
- return { name, target, cases, virtual: input.virtual === true };
2264
+ return {
2265
+ name,
2266
+ target,
2267
+ cases,
2268
+ virtual: input.virtual === true,
2269
+ ...input.recordedToolMode !== void 0 ? { recordedToolMode: input.recordedToolMode } : {},
2270
+ ...input.recordedToolUnmatchedPolicy !== void 0 ? { recordedToolUnmatchedPolicy: input.recordedToolUnmatchedPolicy } : {}
2271
+ };
2280
2272
  }
2281
2273
  function normalizeForHash(value) {
2282
2274
  if (Array.isArray(value)) return value.map(normalizeForHash);
@@ -2292,9 +2284,13 @@ function normalizeForHash(value) {
2292
2284
  return value;
2293
2285
  }
2294
2286
  async function computeEvalContentHash(definition) {
2287
+ const recordedToolMode = definition.recordedToolMode ?? "next_step";
2288
+ const recordedToolUnmatchedPolicy = definition.recordedToolUnmatchedPolicy ?? "fail";
2295
2289
  const canonical = {
2296
2290
  target: normalizeForHash(definition.target),
2297
2291
  virtual: definition.virtual,
2292
+ ...recordedToolMode !== "next_step" ? { recordedToolMode } : {},
2293
+ ...recordedToolUnmatchedPolicy !== "fail" ? { recordedToolUnmatchedPolicy } : {},
2298
2294
  cases: [...definition.cases].sort((a, b) => a.name < b.name ? -1 : a.name > b.name ? 1 : 0).map((c) => ({
2299
2295
  name: c.name,
2300
2296
  input: normalizeForHash(c.input),
@@ -2303,10 +2299,7 @@ async function computeEvalContentHash(definition) {
2303
2299
  expect: c.expect.map((g) => normalizeForHash(g))
2304
2300
  }))
2305
2301
  };
2306
- const serialized = JSON.stringify(canonical);
2307
- const encoded = new TextEncoder().encode(serialized);
2308
- const hashBuffer = await crypto.subtle.digest("SHA-256", encoded);
2309
- return Array.from(new Uint8Array(hashBuffer)).map((b) => b.toString(16).padStart(2, "0")).join("");
2302
+ return sha256Hex(JSON.stringify(canonical));
2310
2303
  }
2311
2304
  var serverHashMemo = /* @__PURE__ */ new WeakMap();
2312
2305
  function memoFor(client) {
@@ -2353,11 +2346,8 @@ async function runEvalSuite(client, input) {
2353
2346
  }
2354
2347
 
2355
2348
  // src/flows-ensure.ts
2356
- function isPlainObject2(value) {
2357
- return value !== null && typeof value === "object" && !Array.isArray(value);
2358
- }
2359
2349
  function normalizeConfigForHash(config) {
2360
- if (!isPlainObject2(config)) return {};
2350
+ if (!isPlainObject(config)) return {};
2361
2351
  const normalized = {};
2362
2352
  for (const key of Object.keys(config).sort()) {
2363
2353
  const value = config[key];
@@ -2378,7 +2368,7 @@ function normalizeConfigForHash(config) {
2378
2368
  return normalized;
2379
2369
  }
2380
2370
  function normalizeStepForHash(step) {
2381
- const stepObj = isPlainObject2(step) ? step : {};
2371
+ const stepObj = isPlainObject(step) ? step : {};
2382
2372
  return {
2383
2373
  type: typeof stepObj.type === "string" ? stepObj.type : "",
2384
2374
  name: typeof stepObj.name === "string" ? stepObj.name : "",
@@ -2390,14 +2380,11 @@ function normalizeStepForHash(step) {
2390
2380
  }
2391
2381
  async function computeFlowContentHash(steps) {
2392
2382
  const normalized = [...steps].sort((a, b) => {
2393
- const orderA = isPlainObject2(a) && typeof a.order === "number" ? a.order : 0;
2394
- const orderB = isPlainObject2(b) && typeof b.order === "number" ? b.order : 0;
2383
+ const orderA = isPlainObject(a) && typeof a.order === "number" ? a.order : 0;
2384
+ const orderB = isPlainObject(b) && typeof b.order === "number" ? b.order : 0;
2395
2385
  return orderA - orderB;
2396
2386
  }).map(normalizeStepForHash);
2397
- const serialized = JSON.stringify(normalized);
2398
- const encoded = new TextEncoder().encode(serialized);
2399
- const hashBuffer = await crypto.subtle.digest("SHA-256", encoded);
2400
- return Array.from(new Uint8Array(hashBuffer)).map((b) => b.toString(16).padStart(2, "0")).join("");
2387
+ return sha256Hex(JSON.stringify(normalized));
2401
2388
  }
2402
2389
  var DEFINE_FLOW_TOP_LEVEL_KEYS = /* @__PURE__ */ new Set(["name", "steps", "evals"]);
2403
2390
  var DEFINE_FLOW_STEP_KEYS = /* @__PURE__ */ new Set([
@@ -2420,27 +2407,27 @@ function collectStepNonPortableToolRefs(config, path) {
2420
2407
  });
2421
2408
  };
2422
2409
  const scanKeys = (value, subPath) => {
2423
- if (!isPlainObject2(value)) return;
2410
+ if (!isPlainObject(value)) return;
2424
2411
  for (const key of Object.keys(value)) {
2425
2412
  if (isAccountScoped(key)) found.push(`${subPath}.${key}`);
2426
2413
  }
2427
2414
  };
2428
- if (isPlainObject2(tools)) {
2415
+ if (isPlainObject(tools)) {
2429
2416
  scanArray(tools.toolIds, `${path}.tools.toolIds`);
2430
2417
  scanKeys(tools.toolConfigs, `${path}.tools.toolConfigs`);
2431
2418
  scanKeys(tools.perToolLimits, `${path}.tools.perToolLimits`);
2432
- if (isPlainObject2(tools.approval)) {
2419
+ if (isPlainObject(tools.approval)) {
2433
2420
  scanArray(tools.approval.require, `${path}.tools.approval.require`);
2434
2421
  }
2435
- if (isPlainObject2(tools.subagentConfig)) {
2422
+ if (isPlainObject(tools.subagentConfig)) {
2436
2423
  scanArray(tools.subagentConfig.toolPool, `${path}.tools.subagentConfig.toolPool`);
2437
2424
  }
2438
- if (isPlainObject2(tools.codeModeConfig)) {
2425
+ if (isPlainObject(tools.codeModeConfig)) {
2439
2426
  scanArray(tools.codeModeConfig.toolPool, `${path}.tools.codeModeConfig.toolPool`);
2440
2427
  }
2441
2428
  if (Array.isArray(tools.runtimeTools)) {
2442
2429
  tools.runtimeTools.forEach((runtimeTool, i) => {
2443
- if (!isPlainObject2(runtimeTool) || !isPlainObject2(runtimeTool.config)) return;
2430
+ if (!isPlainObject(runtimeTool) || !isPlainObject(runtimeTool.config)) return;
2444
2431
  const base = `${path}.tools.runtimeTools[${i}].config`;
2445
2432
  const rtConfig = runtimeTool.config;
2446
2433
  if (runtimeTool.toolType === "subagent" && isRawId(rtConfig.agentId, "agent_")) {
@@ -2461,7 +2448,7 @@ function collectStepNonPortableToolRefs(config, path) {
2461
2448
  const nested = config[branch];
2462
2449
  if (!Array.isArray(nested)) continue;
2463
2450
  nested.forEach((nestedStep, i) => {
2464
- if (isPlainObject2(nestedStep) && isPlainObject2(nestedStep.config)) {
2451
+ if (isPlainObject(nestedStep) && isPlainObject(nestedStep.config)) {
2465
2452
  found.push(
2466
2453
  ...collectStepNonPortableToolRefs(nestedStep.config, `${path}.${branch}[${i}].config`)
2467
2454
  );
@@ -2487,7 +2474,7 @@ function defineFlow(input) {
2487
2474
  throw new Error('defineFlow requires a non-empty "steps" array');
2488
2475
  }
2489
2476
  const steps = input.steps.map((step, index) => {
2490
- if (!isPlainObject2(step)) {
2477
+ if (!isPlainObject(step)) {
2491
2478
  throw new Error(`defineFlow: steps[${index}] must be an object`);
2492
2479
  }
2493
2480
  if (typeof step.type !== "string" || step.type.length === 0) {
@@ -2502,7 +2489,7 @@ function defineFlow(input) {
2502
2489
  `defineFlow: steps[${index}] has unknown field(s): ${unknownStepKeys.join(", ")}. Allowed step fields are type, name, order, enabled, when, config. (Step ids are server artifacts and not part of a portable definition.)`
2503
2490
  );
2504
2491
  }
2505
- const config = isPlainObject2(step.config) ? step.config : void 0;
2492
+ const config = isPlainObject(step.config) ? step.config : void 0;
2506
2493
  if (config) {
2507
2494
  const nonPortable = collectStepNonPortableToolRefs(config, `steps[${index}].config`);
2508
2495
  if (nonPortable.length > 0) {
@@ -2529,7 +2516,7 @@ function defineFlow(input) {
2529
2516
  }
2530
2517
  const seenEvalNames = /* @__PURE__ */ new Set();
2531
2518
  evals = input.evals.map((evalInput, i) => {
2532
- if (!isPlainObject2(evalInput)) {
2519
+ if (!isPlainObject(evalInput)) {
2533
2520
  throw new Error(`defineFlow: evals[${i}] must be an object`);
2534
2521
  }
2535
2522
  if (evalInput.virtual === true) {
@@ -2593,7 +2580,7 @@ function parseRequestError(err) {
2593
2580
  }
2594
2581
  function toConflictError(err) {
2595
2582
  const { status, body } = parseRequestError(err);
2596
- if (status !== 409 || !isPlainObject2(body)) return null;
2583
+ if (status !== 409 || !isPlainObject(body)) return null;
2597
2584
  const code = body.code;
2598
2585
  if (code !== "external_modification" && code !== "remote_changed") return null;
2599
2586
  return new FlowEnsureConflictError(
@@ -2958,6 +2945,7 @@ var RuntypeFlowBuilder = class {
2958
2945
  markdownIfAvailable: config.markdownIfAvailable,
2959
2946
  fetchMethod: config.fetchMethod === "http" ? "standard" : config.fetchMethod,
2960
2947
  firecrawl: config.firecrawl,
2948
+ massive: config.massive,
2961
2949
  outputVariable: config.outputVariable,
2962
2950
  errorHandling: config.errorHandling,
2963
2951
  defaultValue: config.defaultValue,
@@ -3118,7 +3106,6 @@ var RuntypeFlowBuilder = class {
3118
3106
  fieldsToExclude: config.fieldsToExclude,
3119
3107
  availableFields: config.availableFields,
3120
3108
  outputVariable: config.outputVariable,
3121
- fields: config.fields,
3122
3109
  includeMetadata: config.includeMetadata,
3123
3110
  streamOutput: config.streamOutput
3124
3111
  },
@@ -3211,7 +3198,6 @@ var RuntypeFlowBuilder = class {
3211
3198
  vectorStore: config.vectorStore,
3212
3199
  weaviateConfig: config.weaviateConfig,
3213
3200
  vectorizeConfig: config.vectorizeConfig,
3214
- pineconeConfig: config.pineconeConfig,
3215
3201
  limit: config.limit,
3216
3202
  threshold: config.threshold,
3217
3203
  metadataFilters: config.metadataFilters,
@@ -3240,7 +3226,6 @@ var RuntypeFlowBuilder = class {
3240
3226
  recordType: config.recordType,
3241
3227
  recordName: config.recordName,
3242
3228
  textField: config.textField,
3243
- storeInRecord: config.storeInRecord,
3244
3229
  embeddingModel: config.embeddingModel,
3245
3230
  maxLength: config.maxLength,
3246
3231
  inputMode: config.inputMode,
@@ -3248,7 +3233,6 @@ var RuntypeFlowBuilder = class {
3248
3233
  itemAlias: config.itemAlias,
3249
3234
  textTemplate: config.textTemplate,
3250
3235
  batchSize: config.batchSize,
3251
- vectorStore: config.vectorStore,
3252
3236
  outputVariable: config.outputVariable,
3253
3237
  streamOutput: config.streamOutput
3254
3238
  },
@@ -3297,51 +3281,6 @@ var RuntypeFlowBuilder = class {
3297
3281
  );
3298
3282
  return this;
3299
3283
  }
3300
- /**
3301
- * Add a send text step
3302
- */
3303
- sendText(config) {
3304
- this.addStep(
3305
- "send-text",
3306
- config.name,
3307
- {
3308
- to: config.to,
3309
- from: config.from,
3310
- message: config.message,
3311
- outputVariable: config.outputVariable,
3312
- errorHandling: config.errorHandling,
3313
- streamOutput: config.streamOutput
3314
- },
3315
- config.enabled,
3316
- config.when
3317
- );
3318
- return this;
3319
- }
3320
- /**
3321
- * Add a fetch GitHub step
3322
- */
3323
- fetchGitHub(config) {
3324
- this.addStep(
3325
- "fetch-github",
3326
- config.name,
3327
- {
3328
- repository: config.repository,
3329
- branch: config.branch,
3330
- path: config.path,
3331
- token: config.token,
3332
- outputVariable: config.outputVariable,
3333
- contentType: config.contentType,
3334
- includePatterns: config.includePatterns,
3335
- excludePatterns: config.excludePatterns,
3336
- compress: config.compress,
3337
- style: config.style,
3338
- streamOutput: config.streamOutput
3339
- },
3340
- config.enabled,
3341
- config.when
3342
- );
3343
- return this;
3344
- }
3345
3284
  /** Add an api-call step. */
3346
3285
  apiCall(config) {
3347
3286
  return this.addRawStep("api-call", config);
@@ -3888,6 +3827,30 @@ var EvalSuitesNamespace = class {
3888
3827
  cases
3889
3828
  });
3890
3829
  }
3830
+ /**
3831
+ * Capture a test case from a real agent run ("fork here and test the next
3832
+ * step"): freezes the run's conversation history up to a fork point, attaches
3833
+ * every recorded tool result as an editable mock, and saves it with origin
3834
+ * `saved_from_run`. Capture only — reads the run, never re-executes it.
3835
+ */
3836
+ async addCaseFromExecution(suiteId, input) {
3837
+ return this.getClient().post(
3838
+ `/eval/suites/${suiteId}/cases/from-execution`,
3839
+ input
3840
+ );
3841
+ }
3842
+ /**
3843
+ * Dry-run of {@link addCaseFromExecution}: reconstruct an agent execution
3844
+ * exactly as capture would and return its recorded actions plus the fork
3845
+ * index each maps to (and whether the case would be fully replayable), so a
3846
+ * caller can build a fork picker without re-deriving the seed math. Reads
3847
+ * only — nothing is written.
3848
+ */
3849
+ async getCapturePreview(executionId) {
3850
+ return this.getClient().get(
3851
+ `/eval/executions/${executionId}/capture-preview`
3852
+ );
3853
+ }
3891
3854
  /** Edit, enable, or disable a test case. */
3892
3855
  async updateCase(suiteId, caseId, input) {
3893
3856
  return this.getClient().patch(
@@ -3901,6 +3864,55 @@ var EvalSuitesNamespace = class {
3901
3864
  `/eval/suites/${suiteId}/cases/${caseId}`
3902
3865
  );
3903
3866
  }
3867
+ /**
3868
+ * List a suite's machine-proposed cases (the review queue). Every
3869
+ * generation source lands here; nothing enters the suite without an accept.
3870
+ */
3871
+ async listProposals(suiteId, params) {
3872
+ return this.getClient().get(
3873
+ `/eval/suites/${suiteId}/proposals`,
3874
+ params
3875
+ );
3876
+ }
3877
+ /**
3878
+ * Accept a proposal — materializes it as an eval case and backlinks it.
3879
+ * Pass `options.case` to save an edited body instead (recorded as
3880
+ * `edited_accepted`; the machine original stays on the proposal for audit).
3881
+ */
3882
+ async acceptProposal(suiteId, proposalId, options) {
3883
+ return this.getClient().post(
3884
+ `/eval/suites/${suiteId}/proposals/${proposalId}/accept`,
3885
+ options ?? {}
3886
+ );
3887
+ }
3888
+ /** Reject a proposal. The row survives as audit. */
3889
+ async rejectProposal(suiteId, proposalId) {
3890
+ return this.getClient().post(
3891
+ `/eval/suites/${suiteId}/proposals/${proposalId}/reject`,
3892
+ {}
3893
+ );
3894
+ }
3895
+ /**
3896
+ * Generate test-case proposals from the target's definition, fanned out
3897
+ * over an explicit diversity matrix (category × persona) and filtered for
3898
+ * gradeability. Results land as PROPOSALS for review — never directly in
3899
+ * the suite. Reserves one daily-eval quota slot per call.
3900
+ */
3901
+ async generateCases(suiteId, input) {
3902
+ return this.getClient().post(
3903
+ `/eval/suites/${suiteId}/generate-cases`,
3904
+ input ?? {}
3905
+ );
3906
+ }
3907
+ /**
3908
+ * The coverage meter: which of the target's tools and instruction clauses
3909
+ * the suite's cases and graders already exercise. The instruction inventory
3910
+ * is cached server-side and refreshed when the definition changes; a cache
3911
+ * miss spends a metered model call, so this requires eval-write scope.
3912
+ */
3913
+ async getCoverage(suiteId) {
3914
+ return this.getClient().get(`/eval/suites/${suiteId}/coverage`);
3915
+ }
3904
3916
  };
3905
3917
 
3906
3918
  // src/evals-namespace.ts
@@ -4074,6 +4086,30 @@ var EvalsNamespace = class {
4074
4086
  async pull(name) {
4075
4087
  return pullEval(this.getClient(), name);
4076
4088
  }
4089
+ /**
4090
+ * Split one plain-language AI-grader criterion carrying several obligations
4091
+ * into focused, independently judgeable sub-checks. Authoring assist only:
4092
+ * nothing is persisted — review the proposal, then save each accepted
4093
+ * sub-check as its own AI grader row. A single returned sub-check means the
4094
+ * criterion is already focused.
4095
+ *
4096
+ * @example
4097
+ * ```typescript
4098
+ * const { subChecks } = await Runtype.evals.decomposeCriteria(
4099
+ * 'Confirms the order number before issuing a refund, and never promises a delivery date.'
4100
+ * )
4101
+ * // In a defineEval suite, each accepted sub-check becomes its own judge row:
4102
+ * const graders = subChecks.map((s) => judge(s.criteria))
4103
+ * ```
4104
+ */
4105
+ async decomposeCriteria(criteria) {
4106
+ if (typeof criteria !== "string" || criteria.trim().length === 0) {
4107
+ throw new Error("decomposeCriteria() requires non-empty criteria");
4108
+ }
4109
+ return this.getClient().post("/eval/graders/decompose", {
4110
+ criteria
4111
+ });
4112
+ }
4077
4113
  /**
4078
4114
  * Run an eval suite synchronously and return the suite score + per-case grader
4079
4115
  * outcomes — the executing counterpart of `ensure`, powering the `runtype
@@ -4108,6 +4144,28 @@ var EvalsNamespace = class {
4108
4144
  const client = this.getClient();
4109
4145
  return client.get(`/eval/runs/${runId}/scores`);
4110
4146
  }
4147
+ /**
4148
+ * Record a lightweight human review of one AI-grader verdict ("the grader
4149
+ * got this right / wrong"), using the `scoreId` on a persisted outcome from
4150
+ * `getRunScores`. Reviews accumulate into the suite's judge-trust display
4151
+ * ("agrees with you N of M times"). Pass `null` to clear an earlier review.
4152
+ *
4153
+ * @example
4154
+ * ```typescript
4155
+ * const scores = await Runtype.evals.getRunScores(runId)
4156
+ * const outcome = scores.cases[0]?.outcomes.find((o) => o.kind === 'ai')
4157
+ * if (outcome?.scoreId) {
4158
+ * await Runtype.evals.reviewScore(outcome.scoreId, 'disagree')
4159
+ * }
4160
+ * ```
4161
+ */
4162
+ async reviewScore(scoreId, verdict) {
4163
+ const client = this.getClient();
4164
+ return client.post(
4165
+ `/eval/scores/${scoreId}/review`,
4166
+ { verdict }
4167
+ );
4168
+ }
4111
4169
  /**
4112
4170
  * Get evaluation status by ID
4113
4171
  *
@@ -4226,42 +4284,21 @@ var PromptsNamespace = class {
4226
4284
  };
4227
4285
 
4228
4286
  // src/skills-ensure.ts
4229
- function isPlainObject3(value) {
4230
- return value !== null && typeof value === "object" && !Array.isArray(value);
4231
- }
4232
- function normalizeValue(value) {
4233
- if (Array.isArray(value)) {
4234
- return value.map((item) => normalizeValue(item));
4235
- }
4236
- if (isPlainObject3(value)) {
4237
- const normalized = {};
4238
- for (const key of Object.keys(value).sort()) {
4239
- const entry = value[key];
4240
- if (entry === void 0 || entry === null) continue;
4241
- normalized[key] = normalizeValue(entry);
4242
- }
4243
- return normalized;
4244
- }
4245
- return value;
4246
- }
4247
4287
  function normalizeSkillDefinition(definition) {
4248
- const manifest = isPlainObject3(definition.manifest) ? definition.manifest : {};
4249
- const rawFrontmatter = isPlainObject3(manifest.frontmatter) ? manifest.frontmatter : {};
4288
+ const manifest = isPlainObject(definition.manifest) ? definition.manifest : {};
4289
+ const rawFrontmatter = isPlainObject(manifest.frontmatter) ? manifest.frontmatter : {};
4250
4290
  const frontmatterWithoutName = {};
4251
4291
  for (const key of Object.keys(rawFrontmatter)) {
4252
4292
  if (key === "name") continue;
4253
4293
  frontmatterWithoutName[key] = rawFrontmatter[key];
4254
4294
  }
4255
4295
  const frontmatter = normalizeValue(frontmatterWithoutName);
4256
- const runtype = isPlainObject3(manifest.runtype) ? normalizeValue(manifest.runtype) : {};
4296
+ const runtype = isPlainObject(manifest.runtype) ? normalizeValue(manifest.runtype) : {};
4257
4297
  const body = typeof manifest.body === "string" ? manifest.body : "";
4258
4298
  return { frontmatter, runtype, body };
4259
4299
  }
4260
4300
  async function computeSkillContentHash(definition) {
4261
- const serialized = JSON.stringify(normalizeSkillDefinition(definition));
4262
- const encoded = new TextEncoder().encode(serialized);
4263
- const hashBuffer = await crypto.subtle.digest("SHA-256", encoded);
4264
- return Array.from(new Uint8Array(hashBuffer)).map((b) => b.toString(16).padStart(2, "0")).join("");
4301
+ return sha256Hex(JSON.stringify(normalizeSkillDefinition(definition)));
4265
4302
  }
4266
4303
  var DEFINE_SKILL_TOP_LEVEL_KEYS = /* @__PURE__ */ new Set(["name", "manifest"]);
4267
4304
  function defineSkill(input) {
@@ -4271,7 +4308,7 @@ function defineSkill(input) {
4271
4308
  if (typeof input.name !== "string" || input.name.length === 0) {
4272
4309
  throw new Error('defineSkill requires a non-empty string "name"');
4273
4310
  }
4274
- if (!isPlainObject3(input.manifest)) {
4311
+ if (!isPlainObject(input.manifest)) {
4275
4312
  throw new Error('defineSkill requires a "manifest" object ({ frontmatter, runtype, body })');
4276
4313
  }
4277
4314
  const unknownKeys = Object.keys(input).filter((key) => !DEFINE_SKILL_TOP_LEVEL_KEYS.has(key));
@@ -4281,7 +4318,7 @@ function defineSkill(input) {
4281
4318
  );
4282
4319
  }
4283
4320
  const frontmatter = input.manifest.frontmatter;
4284
- if (!isPlainObject3(frontmatter) || typeof frontmatter.name !== "string") {
4321
+ if (!isPlainObject(frontmatter) || typeof frontmatter.name !== "string") {
4285
4322
  throw new Error("defineSkill: manifest.frontmatter.name is required");
4286
4323
  }
4287
4324
  if (frontmatter.name !== input.name) {
@@ -4322,7 +4359,7 @@ function parseRequestError2(err) {
4322
4359
  }
4323
4360
  function toConflictError2(err) {
4324
4361
  const { status, body } = parseRequestError2(err);
4325
- if (status !== 409 || !isPlainObject3(body)) return null;
4362
+ if (status !== 409 || !isPlainObject(body)) return null;
4326
4363
  const code = body.code;
4327
4364
  if (code !== "external_modification" && code !== "remote_changed") return null;
4328
4365
  return new SkillEnsureConflictError(
@@ -4671,14 +4708,14 @@ var AGENT_CONFIG_KEYS = [
4671
4708
  "tenancyStrategy"
4672
4709
  ];
4673
4710
  var AGENT_CONFIG_KEY_LIST = [...AGENT_CONFIG_KEYS].sort();
4674
- function isPlainObject4(value) {
4711
+ function isPlainObject2(value) {
4675
4712
  return value !== null && typeof value === "object" && !Array.isArray(value);
4676
4713
  }
4677
4714
  function normalizeValue2(value) {
4678
4715
  if (Array.isArray(value)) {
4679
4716
  return value.map((item) => normalizeValue2(item));
4680
4717
  }
4681
- if (isPlainObject4(value)) {
4718
+ if (isPlainObject2(value)) {
4682
4719
  const normalized = {};
4683
4720
  for (const key of Object.keys(value).sort()) {
4684
4721
  const entry = value[key];
@@ -4691,7 +4728,7 @@ function normalizeValue2(value) {
4691
4728
  }
4692
4729
  function normalizeAgentDefinition(definition) {
4693
4730
  const config = {};
4694
- const rawConfig = isPlainObject4(definition.config) ? definition.config : {};
4731
+ const rawConfig = isPlainObject2(definition.config) ? definition.config : {};
4695
4732
  for (const key of AGENT_CONFIG_KEY_LIST) {
4696
4733
  const value = rawConfig[key];
4697
4734
  if (value === void 0 || value === null) continue;
@@ -4713,7 +4750,7 @@ async function computeAgentContentHash(definition) {
4713
4750
  var DEFINE_TOP_LEVEL_KEYS = /* @__PURE__ */ new Set(["name", "description", "icon", ...AGENT_CONFIG_KEYS]);
4714
4751
  function collectNonPortableToolRefs(config) {
4715
4752
  const tools = config.tools;
4716
- if (!isPlainObject4(tools)) return [];
4753
+ if (!isPlainObject2(tools)) return [];
4717
4754
  const found = [];
4718
4755
  const isAccountScoped = (ref) => typeof ref === "string" && ref.startsWith("tool_");
4719
4756
  const scanArray = (value, path) => {
@@ -4723,7 +4760,7 @@ function collectNonPortableToolRefs(config) {
4723
4760
  });
4724
4761
  };
4725
4762
  const scanKeys = (value, path) => {
4726
- if (!isPlainObject4(value)) return;
4763
+ if (!isPlainObject2(value)) return;
4727
4764
  for (const key of Object.keys(value)) {
4728
4765
  if (isAccountScoped(key)) found.push(`${path}.${key}`);
4729
4766
  }
@@ -4731,16 +4768,16 @@ function collectNonPortableToolRefs(config) {
4731
4768
  scanArray(tools.toolIds, "tools.toolIds");
4732
4769
  scanKeys(tools.toolConfigs, "tools.toolConfigs");
4733
4770
  scanKeys(tools.perToolLimits, "tools.perToolLimits");
4734
- if (isPlainObject4(tools.approval)) scanArray(tools.approval.require, "tools.approval.require");
4735
- if (isPlainObject4(tools.subagentConfig)) {
4771
+ if (isPlainObject2(tools.approval)) scanArray(tools.approval.require, "tools.approval.require");
4772
+ if (isPlainObject2(tools.subagentConfig)) {
4736
4773
  scanArray(tools.subagentConfig.toolPool, "tools.subagentConfig.toolPool");
4737
4774
  }
4738
- if (isPlainObject4(tools.codeModeConfig)) {
4775
+ if (isPlainObject2(tools.codeModeConfig)) {
4739
4776
  scanArray(tools.codeModeConfig.toolPool, "tools.codeModeConfig.toolPool");
4740
4777
  }
4741
4778
  if (Array.isArray(tools.runtimeTools)) {
4742
4779
  tools.runtimeTools.forEach((runtimeTool, i) => {
4743
- if (!isPlainObject4(runtimeTool) || !isPlainObject4(runtimeTool.config)) return;
4780
+ if (!isPlainObject2(runtimeTool) || !isPlainObject2(runtimeTool.config)) return;
4744
4781
  const base = `tools.runtimeTools[${i}].config`;
4745
4782
  const rtConfig = runtimeTool.config;
4746
4783
  if (runtimeTool.toolType === "subagent" && typeof rtConfig.agentId === "string" && rtConfig.agentId.startsWith("agent_")) {
@@ -4814,7 +4851,7 @@ function parseRequestError3(err) {
4814
4851
  }
4815
4852
  function toConflictError3(err) {
4816
4853
  const { status, body } = parseRequestError3(err);
4817
- if (status !== 409 || !isPlainObject4(body)) return null;
4854
+ if (status !== 409 || !isPlainObject2(body)) return null;
4818
4855
  const code = body.code;
4819
4856
  if (code !== "external_modification" && code !== "remote_changed") return null;
4820
4857
  return new AgentEnsureConflictError(
@@ -4916,27 +4953,9 @@ var AgentsNamespace = class {
4916
4953
  };
4917
4954
 
4918
4955
  // src/tools-ensure.ts
4919
- function isPlainObject5(value) {
4920
- return value !== null && typeof value === "object" && !Array.isArray(value);
4921
- }
4922
- function normalizeValue3(value) {
4923
- if (Array.isArray(value)) {
4924
- return value.map((item) => normalizeValue3(item));
4925
- }
4926
- if (isPlainObject5(value)) {
4927
- const normalized = {};
4928
- for (const key of Object.keys(value).sort()) {
4929
- const entry = value[key];
4930
- if (entry === void 0 || entry === null) continue;
4931
- normalized[key] = normalizeValue3(entry);
4932
- }
4933
- return normalized;
4934
- }
4935
- return value;
4936
- }
4937
4956
  function normalizeToolDefinition(definition) {
4938
- const parametersSchema = isPlainObject5(definition.parametersSchema) ? normalizeValue3(definition.parametersSchema) : {};
4939
- const config = isPlainObject5(definition.config) ? normalizeValue3(definition.config) : {};
4957
+ const parametersSchema = isPlainObject(definition.parametersSchema) ? normalizeValue(definition.parametersSchema) : {};
4958
+ const config = isPlainObject(definition.config) ? normalizeValue(definition.config) : {};
4940
4959
  return {
4941
4960
  toolType: definition.toolType,
4942
4961
  ...definition.description ? { description: definition.description } : {},
@@ -4945,10 +4964,7 @@ function normalizeToolDefinition(definition) {
4945
4964
  };
4946
4965
  }
4947
4966
  async function computeToolContentHash(definition) {
4948
- const serialized = JSON.stringify(normalizeToolDefinition(definition));
4949
- const encoded = new TextEncoder().encode(serialized);
4950
- const hashBuffer = await crypto.subtle.digest("SHA-256", encoded);
4951
- return Array.from(new Uint8Array(hashBuffer)).map((b) => b.toString(16).padStart(2, "0")).join("");
4967
+ return sha256Hex(JSON.stringify(normalizeToolDefinition(definition)));
4952
4968
  }
4953
4969
  var DEFINE_TOOL_TOP_LEVEL_KEYS = /* @__PURE__ */ new Set([
4954
4970
  "name",
@@ -4981,10 +4997,10 @@ function defineTool(input) {
4981
4997
  `defineTool requires "toolType" to be one of: ${[...TOOL_DEFINITION_TYPES].join(", ")}`
4982
4998
  );
4983
4999
  }
4984
- if (!isPlainObject5(input.parametersSchema)) {
5000
+ if (!isPlainObject(input.parametersSchema)) {
4985
5001
  throw new Error('defineTool requires a "parametersSchema" object (a JSON Schema)');
4986
5002
  }
4987
- if (!isPlainObject5(input.config)) {
5003
+ if (!isPlainObject(input.config)) {
4988
5004
  throw new Error('defineTool requires a "config" object');
4989
5005
  }
4990
5006
  const unknownKeys = Object.keys(input).filter((key) => !DEFINE_TOOL_TOP_LEVEL_KEYS.has(key));
@@ -5032,7 +5048,7 @@ function parseRequestError4(err) {
5032
5048
  }
5033
5049
  function toConflictError4(err) {
5034
5050
  const { status, body } = parseRequestError4(err);
5035
- if (status !== 409 || !isPlainObject5(body)) return null;
5051
+ if (status !== 409 || !isPlainObject(body)) return null;
5036
5052
  const code = body.code;
5037
5053
  if (code !== "external_modification" && code !== "remote_changed") return null;
5038
5054
  return new ToolEnsureConflictError(
@@ -5152,26 +5168,8 @@ var ToolsNamespace = class {
5152
5168
  };
5153
5169
 
5154
5170
  // src/products-ensure.ts
5155
- function isPlainObject6(value) {
5156
- return value !== null && typeof value === "object" && !Array.isArray(value);
5157
- }
5158
- function normalizeValue4(value) {
5159
- if (Array.isArray(value)) {
5160
- return value.map((item) => normalizeValue4(item));
5161
- }
5162
- if (isPlainObject6(value)) {
5163
- const normalized = {};
5164
- for (const key of Object.keys(value).sort()) {
5165
- const entry = value[key];
5166
- if (entry === void 0 || entry === null) continue;
5167
- normalized[key] = normalizeValue4(entry);
5168
- }
5169
- return normalized;
5170
- }
5171
- return value;
5172
- }
5173
5171
  function normalizeProductDefinition(definition) {
5174
- const spec = isPlainObject6(definition.spec) ? normalizeValue4(definition.spec) : {};
5172
+ const spec = isPlainObject(definition.spec) ? normalizeValue(definition.spec) : {};
5175
5173
  return {
5176
5174
  ...definition.description ? { description: definition.description } : {},
5177
5175
  ...definition.icon ? { icon: definition.icon } : {},
@@ -5179,10 +5177,7 @@ function normalizeProductDefinition(definition) {
5179
5177
  };
5180
5178
  }
5181
5179
  async function computeProductContentHash(definition) {
5182
- const serialized = JSON.stringify(normalizeProductDefinition(definition));
5183
- const encoded = new TextEncoder().encode(serialized);
5184
- const hashBuffer = await crypto.subtle.digest("SHA-256", encoded);
5185
- return Array.from(new Uint8Array(hashBuffer)).map((b) => b.toString(16).padStart(2, "0")).join("");
5180
+ return sha256Hex(JSON.stringify(normalizeProductDefinition(definition)));
5186
5181
  }
5187
5182
  var DEFINE_PRODUCT_TOP_LEVEL_KEYS = /* @__PURE__ */ new Set(["name", "description", "icon", "spec"]);
5188
5183
  function defineProduct(input) {
@@ -5198,7 +5193,7 @@ function defineProduct(input) {
5198
5193
  if (input.icon != null && typeof input.icon !== "string") {
5199
5194
  throw new Error('defineProduct "icon" must be a string when provided');
5200
5195
  }
5201
- if (input.spec != null && !isPlainObject6(input.spec)) {
5196
+ if (input.spec != null && !isPlainObject(input.spec)) {
5202
5197
  throw new Error('defineProduct "spec" must be an object when provided');
5203
5198
  }
5204
5199
  const unknownKeys = Object.keys(input).filter((key) => !DEFINE_PRODUCT_TOP_LEVEL_KEYS.has(key));
@@ -5245,7 +5240,7 @@ function parseRequestError5(err) {
5245
5240
  }
5246
5241
  function toConflictError5(err) {
5247
5242
  const { status, body } = parseRequestError5(err);
5248
- if (status !== 409 || !isPlainObject6(body)) return null;
5243
+ if (status !== 409 || !isPlainObject(body)) return null;
5249
5244
  const code = body.code;
5250
5245
  if (code !== "external_modification" && code !== "remote_changed") return null;
5251
5246
  return new ProductEnsureConflictError(
@@ -5326,50 +5321,31 @@ async function pullProduct(client, name) {
5326
5321
  }
5327
5322
 
5328
5323
  // src/products-ensure-fpo.ts
5329
- function isPlainObject7(value) {
5330
- return value !== null && typeof value === "object" && !Array.isArray(value);
5331
- }
5332
- function normalizeValue5(value) {
5333
- if (Array.isArray(value)) {
5334
- return value.map((item) => normalizeValue5(item));
5335
- }
5336
- if (isPlainObject7(value)) {
5337
- const normalized = {};
5338
- for (const key of Object.keys(value).sort()) {
5339
- const entry = value[key];
5340
- if (entry === void 0 || entry === null) continue;
5341
- normalized[key] = normalizeValue5(entry);
5342
- }
5343
- return normalized;
5344
- }
5345
- return value;
5346
- }
5347
5324
  function normalizeFpoDefinition(fpo) {
5348
- const productInput = isPlainObject7(fpo.product) ? fpo.product : {};
5325
+ const productInput = isPlainObject(fpo.product) ? fpo.product : {};
5349
5326
  const { name: _identityName, ...productRest } = productInput;
5350
- const product = normalizeValue5(productRest);
5327
+ const product = normalizeValue(productRest);
5351
5328
  return {
5352
- ...fpo.version !== void 0 && fpo.version !== null ? { version: normalizeValue5(fpo.version) } : {},
5329
+ ...fpo.version !== void 0 && fpo.version !== null ? { version: normalizeValue(fpo.version) } : {},
5353
5330
  product,
5354
- capabilities: normalizeValue5(fpo.capabilities ?? []),
5355
- tools: normalizeValue5(fpo.tools ?? []),
5356
- surfaces: normalizeValue5(fpo.surfaces ?? []),
5357
- ...fpo.records !== void 0 && fpo.records !== null ? { records: normalizeValue5(fpo.records) } : {},
5358
- ...fpo.schedules !== void 0 && fpo.schedules !== null ? { schedules: normalizeValue5(fpo.schedules) } : {},
5359
- ...fpo.secrets !== void 0 && fpo.secrets !== null ? { secrets: normalizeValue5(fpo.secrets) } : {}
5331
+ capabilities: normalizeValue(fpo.capabilities ?? []),
5332
+ tools: normalizeValue(fpo.tools ?? []),
5333
+ surfaces: normalizeValue(fpo.surfaces ?? []),
5334
+ ...fpo.records !== void 0 && fpo.records !== null ? { records: normalizeValue(fpo.records) } : {},
5335
+ ...fpo.schedules !== void 0 && fpo.schedules !== null ? { schedules: normalizeValue(fpo.schedules) } : {},
5336
+ ...fpo.secrets !== void 0 && fpo.secrets !== null ? { secrets: normalizeValue(fpo.secrets) } : {},
5337
+ ...fpo.evals !== void 0 && fpo.evals !== null ? { evals: normalizeValue(fpo.evals) } : {},
5338
+ ...fpo.skills !== void 0 && fpo.skills !== null ? { skills: normalizeValue(fpo.skills) } : {}
5360
5339
  };
5361
5340
  }
5362
5341
  async function computeFpoContentHash(fpo) {
5363
- const serialized = JSON.stringify(normalizeFpoDefinition(fpo));
5364
- const encoded = new TextEncoder().encode(serialized);
5365
- const hashBuffer = await crypto.subtle.digest("SHA-256", encoded);
5366
- return Array.from(new Uint8Array(hashBuffer)).map((b) => b.toString(16).padStart(2, "0")).join("");
5342
+ return sha256Hex(JSON.stringify(normalizeFpoDefinition(fpo)));
5367
5343
  }
5368
5344
  function defineFpo(fpo) {
5369
- if (!isPlainObject7(fpo)) {
5345
+ if (!isPlainObject(fpo)) {
5370
5346
  throw new Error("defineFpo requires an FPO object");
5371
5347
  }
5372
- const product = isPlainObject7(fpo.product) ? fpo.product : void 0;
5348
+ const product = isPlainObject(fpo.product) ? fpo.product : void 0;
5373
5349
  if (!product || typeof product.name !== "string" || product.name.length === 0) {
5374
5350
  throw new Error('defineFpo requires a non-empty "product.name" (the converge identity)');
5375
5351
  }
@@ -5465,26 +5441,8 @@ var ProductsNamespace = class {
5465
5441
  };
5466
5442
 
5467
5443
  // src/surfaces-ensure.ts
5468
- function isPlainObject8(value) {
5469
- return value !== null && typeof value === "object" && !Array.isArray(value);
5470
- }
5471
- function normalizeValue6(value) {
5472
- if (Array.isArray(value)) {
5473
- return value.map((item) => normalizeValue6(item));
5474
- }
5475
- if (isPlainObject8(value)) {
5476
- const normalized = {};
5477
- for (const key of Object.keys(value).sort()) {
5478
- const entry = value[key];
5479
- if (entry === void 0 || entry === null) continue;
5480
- normalized[key] = normalizeValue6(entry);
5481
- }
5482
- return normalized;
5483
- }
5484
- return value;
5485
- }
5486
5444
  function normalizeSurfaceDefinition(definition) {
5487
- const behavior = isPlainObject8(definition.behavior) ? normalizeValue6({ type: definition.type, ...definition.behavior }) : { type: definition.type };
5445
+ const behavior = isPlainObject(definition.behavior) ? normalizeValue({ type: definition.type, ...definition.behavior }) : { type: definition.type };
5488
5446
  return {
5489
5447
  type: definition.type,
5490
5448
  behavior,
@@ -5493,10 +5451,7 @@ function normalizeSurfaceDefinition(definition) {
5493
5451
  };
5494
5452
  }
5495
5453
  async function computeSurfaceContentHash(definition) {
5496
- const serialized = JSON.stringify(normalizeSurfaceDefinition(definition));
5497
- const encoded = new TextEncoder().encode(serialized);
5498
- const hashBuffer = await crypto.subtle.digest("SHA-256", encoded);
5499
- return Array.from(new Uint8Array(hashBuffer)).map((b) => b.toString(16).padStart(2, "0")).join("");
5454
+ return sha256Hex(JSON.stringify(normalizeSurfaceDefinition(definition)));
5500
5455
  }
5501
5456
  var DEFINE_SURFACE_TOP_LEVEL_KEYS = /* @__PURE__ */ new Set([
5502
5457
  "name",
@@ -5537,13 +5492,13 @@ function defineSurface(input) {
5537
5492
  `defineSurface requires "type" to be one of: ${[...SURFACE_DEFINITION_TYPES].join(", ")}`
5538
5493
  );
5539
5494
  }
5540
- if (input.behavior !== void 0 && !isPlainObject8(input.behavior)) {
5495
+ if (input.behavior !== void 0 && !isPlainObject(input.behavior)) {
5541
5496
  throw new Error('defineSurface "behavior" must be an object when provided');
5542
5497
  }
5543
- if (input.inbound !== void 0 && !isPlainObject8(input.inbound)) {
5498
+ if (input.inbound !== void 0 && !isPlainObject(input.inbound)) {
5544
5499
  throw new Error('defineSurface "inbound" must be an object when provided');
5545
5500
  }
5546
- if (input.outbound !== void 0 && !isPlainObject8(input.outbound)) {
5501
+ if (input.outbound !== void 0 && !isPlainObject(input.outbound)) {
5547
5502
  throw new Error('defineSurface "outbound" must be an object when provided');
5548
5503
  }
5549
5504
  if (input.status !== void 0 && !["draft", "active", "paused"].includes(input.status)) {
@@ -5599,7 +5554,7 @@ function parseRequestError6(err) {
5599
5554
  }
5600
5555
  function toConflictError6(err) {
5601
5556
  const { status, body } = parseRequestError6(err);
5602
- if (status !== 409 || !isPlainObject8(body)) return null;
5557
+ if (status !== 409 || !isPlainObject(body)) return null;
5603
5558
  const code = body.code;
5604
5559
  if (code !== "external_modification" && code !== "remote_changed") return null;
5605
5560
  return new SurfaceEnsureConflictError(
@@ -6212,7 +6167,7 @@ var Runtype = class {
6212
6167
 
6213
6168
  // src/version.ts
6214
6169
  var FALLBACK_VERSION = "0.0.0";
6215
- var SDK_VERSION = "5.9.0".length > 0 ? "5.9.0" : FALLBACK_VERSION;
6170
+ var SDK_VERSION = "6.1.3".length > 0 ? "6.1.3" : FALLBACK_VERSION;
6216
6171
  var RUNTYPE_CLIENT_KIND = "sdk";
6217
6172
  var SDK_USER_AGENT = `runtype-sdk/${SDK_VERSION} (typescript)`;
6218
6173
 
@@ -8456,6 +8411,69 @@ var RecordsEndpoint = class {
8456
8411
  });
8457
8412
  }
8458
8413
  };
8414
+ var CollectionsEndpoint = class {
8415
+ constructor(client) {
8416
+ this.client = client;
8417
+ }
8418
+ /**
8419
+ * List collections with cursor pagination. `includeCount: true` adds
8420
+ * per-collection record counts.
8421
+ */
8422
+ async list(params) {
8423
+ return this.client.get("/collections", params);
8424
+ }
8425
+ /**
8426
+ * Get a collection by slug. `includeHistory: true` embeds the append-only
8427
+ * schema version history.
8428
+ */
8429
+ async get(slug, params) {
8430
+ return this.client.get(`/collections/${slug}`, params);
8431
+ }
8432
+ /**
8433
+ * Register a record type as a collection. `validationMode` defaults to
8434
+ * `off`, so creating a collection changes no existing behavior.
8435
+ */
8436
+ async create(data) {
8437
+ return this.client.post("/collections", data);
8438
+ }
8439
+ /**
8440
+ * Update display fields, validation mode, or the schema. Breaking schema
8441
+ * changes are rejected while the resulting mode is `enforce`; transitioning
8442
+ * to `enforce` returns an `enforceCheck` dry-run summary.
8443
+ */
8444
+ async update(slug, data) {
8445
+ return this.client.patch(`/collections/${slug}`, data);
8446
+ }
8447
+ /**
8448
+ * Delete the collection REGISTRATION only — records of the type are not
8449
+ * touched and revert to schemaless behavior.
8450
+ */
8451
+ async delete(slug) {
8452
+ return this.client.delete(`/collections/${slug}`);
8453
+ }
8454
+ /**
8455
+ * Sample the type's most recently updated records and return a PROPOSED
8456
+ * schema with per-field confidence and sample values. Saves nothing —
8457
+ * review the proposal, then `update()` the collection.
8458
+ */
8459
+ async inferSchema(slug, params) {
8460
+ return this.client.post(
8461
+ `/collections/${slug}/infer-schema`,
8462
+ params ?? {}
8463
+ );
8464
+ }
8465
+ /**
8466
+ * Dry-run existing records against a schema without writing anything — the
8467
+ * "N of M records would fail" preview before enabling `enforce`. Uses the
8468
+ * provided schema when given, otherwise the collection's saved schema.
8469
+ */
8470
+ async validateExisting(slug, data) {
8471
+ return this.client.post(
8472
+ `/collections/${slug}/validate-existing`,
8473
+ data ?? {}
8474
+ );
8475
+ }
8476
+ };
8459
8477
  var ApiKeysEndpoint = class {
8460
8478
  constructor(client) {
8461
8479
  this.client = client;
@@ -9075,13 +9093,21 @@ var ClientTokensEndpoint = class {
9075
9093
  constructor(client) {
9076
9094
  this.client = client;
9077
9095
  }
9078
- /**
9079
- * List all client tokens for the authenticated user
9080
- */
9081
- async list() {
9082
- const response = await this.client.get(
9083
- "/client-tokens"
9084
- );
9096
+ async list(params) {
9097
+ const response = await this.client.get("/client-tokens", params);
9098
+ if (params?.limit !== void 0) {
9099
+ return {
9100
+ clientTokens: response.clientTokens,
9101
+ // The API always includes pagination when limit is supplied; the
9102
+ // fallback mirrors the server's own envelope math so the paged
9103
+ // overload stays total against older API deployments.
9104
+ pagination: response.pagination ?? {
9105
+ limit: params.limit,
9106
+ offset: params.offset ?? 0,
9107
+ hasMore: response.clientTokens.length === params.limit
9108
+ }
9109
+ };
9110
+ }
9085
9111
  return response.clientTokens;
9086
9112
  }
9087
9113
  /**
@@ -12501,6 +12527,22 @@ var IntegrationsEndpoint = class {
12501
12527
  async installSlack(data) {
12502
12528
  return this.client.post("/integrations/slack/install", data);
12503
12529
  }
12530
+ /**
12531
+ * Start the Slack "Add to Slack" OAuth handshake. Returns the Slack authorize
12532
+ * URL to open in a popup; the bot token is captured server-side by the
12533
+ * callback (never returned to the browser).
12534
+ */
12535
+ async startSlackOAuth(data) {
12536
+ return this.client.post("/oauth/slack/start", data);
12537
+ }
12538
+ /**
12539
+ * Generate the Slack app manifest and one-click create-app deep link for a
12540
+ * surface. The manifest carries absolute API URLs derived server-side, so it
12541
+ * is always valid for Slack (relative proxy paths never leak in).
12542
+ */
12543
+ async generateSlackManifest(data) {
12544
+ return this.client.post("/integrations/slack/manifest", data);
12545
+ }
12504
12546
  };
12505
12547
  var BillingEndpoint = class {
12506
12548
  constructor(client) {
@@ -12519,7 +12561,15 @@ var BillingEndpoint = class {
12519
12561
  return this.client.get("/billing/credits");
12520
12562
  }
12521
12563
  /**
12522
- * Get spend analytics. The window is controlled by `days` (1–365, defaults to 30).
12564
+ * Get the caller's exact current UTC-month platform spend from the local
12565
+ * meter used for spend-cap enforcement. Returns 503 when that meter is unavailable.
12566
+ */
12567
+ async getCurrentSpend() {
12568
+ return this.client.get("/billing/current-spend");
12569
+ }
12570
+ /**
12571
+ * Get spend analytics. The window is controlled by either `period` or `days`
12572
+ * (1–365, defaults to 30).
12523
12573
  */
12524
12574
  async getSpendAnalytics(params) {
12525
12575
  return this.client.get("/billing/spend-analytics", params);
@@ -12548,52 +12598,6 @@ var ToolApprovalGrantsEndpoint = class {
12548
12598
  return this.client.delete(`/tool-approval-grants/${id}`);
12549
12599
  }
12550
12600
  };
12551
- var AppsEndpoint = class {
12552
- constructor(client) {
12553
- this.client = client;
12554
- }
12555
- /** List apps for the authenticated owner, newest first. */
12556
- async list() {
12557
- return this.client.get("/apps");
12558
- }
12559
- /** Get an app by id, including its URL and active version pointer. */
12560
- async get(id) {
12561
- return this.client.get(`/apps/${id}`);
12562
- }
12563
- /** Create an app. A client token scoped to the app origin is auto-provisioned. */
12564
- async create(data) {
12565
- return this.client.post("/apps", data);
12566
- }
12567
- /** Update name, description, visibility, or status (suspended serves 410). */
12568
- async update(id, data) {
12569
- return this.client.patch(`/apps/${id}`, data);
12570
- }
12571
- /** Delete an app, its versions, and its hosting. Irreversible. */
12572
- async delete(id) {
12573
- return this.client.delete(`/apps/${id}`);
12574
- }
12575
- /** List an app's versions, newest first. */
12576
- async listVersions(id) {
12577
- return this.client.get(`/apps/${id}/versions`);
12578
- }
12579
- /** Upload a zipped bundle (raw application/zip body) as a new version. */
12580
- async uploadVersion(id, zipBytes) {
12581
- return this.client.postBinary(`/apps/${id}/versions`, zipBytes, "application/zip");
12582
- }
12583
- /**
12584
- * Upload a bundle from in-memory file maps (the API zips server-side).
12585
- * Text files in `files`, binary files base64-encoded in `filesBase64`.
12586
- */
12587
- async uploadVersionFiles(id, data) {
12588
- return this.client.post(`/apps/${id}/versions`, data);
12589
- }
12590
- /** Activate an uploaded version (deploy or rollback). */
12591
- async activate(id, versionId) {
12592
- return this.client.post(`/apps/${id}/activate`, {
12593
- versionId
12594
- });
12595
- }
12596
- };
12597
12601
 
12598
12602
  // src/client.ts
12599
12603
  function isObjectRecord(value) {
@@ -12630,6 +12634,7 @@ var RuntypeClient2 = class {
12630
12634
  this.flows = new FlowsEndpoint(this);
12631
12635
  this.prompts = new PromptsEndpoint(this);
12632
12636
  this.records = new RecordsEndpoint(this);
12637
+ this.collections = new CollectionsEndpoint(this);
12633
12638
  this.apiKeys = new ApiKeysEndpoint(this);
12634
12639
  this.modelConfigs = new ModelConfigsEndpoint(this);
12635
12640
  this.providerKeys = new ProviderKeysEndpoint(this);
@@ -12644,7 +12649,6 @@ var RuntypeClient2 = class {
12644
12649
  this.clientTokens = new ClientTokensEndpoint(this);
12645
12650
  this.agents = new AgentsEndpoint(this);
12646
12651
  this.secrets = new SecretsEndpoint(this);
12647
- this.apps = new AppsEndpoint(this);
12648
12652
  this.schedules = new SchedulesEndpoint(this);
12649
12653
  this.surfaces = new SurfacesEndpoint(this);
12650
12654
  this.conversations = new ConversationsEndpoint(this);
@@ -13467,6 +13471,7 @@ var FETCH_URL_FIELDS = [
13467
13471
  { key: "markdownIfAvailable", format: "raw" },
13468
13472
  { key: "fetchMethod", format: "json", skipDefault: "standard" },
13469
13473
  { key: "firecrawl", format: "value" },
13474
+ { key: "massive", format: "value" },
13470
13475
  { key: "outputVariable", format: "json" },
13471
13476
  { key: "streamOutput", format: "raw" },
13472
13477
  { key: "errorHandling", format: "value", skipDefault: "fail" },
@@ -13530,7 +13535,10 @@ var SEND_EMAIL_FIELDS = [
13530
13535
  { key: "defaultValue", format: "value" }
13531
13536
  ];
13532
13537
  var SEND_STREAM_FIELDS = [
13533
- { key: "message", format: "template" }
13538
+ { key: "message", format: "template" },
13539
+ { key: "outputVariable", format: "json" },
13540
+ { key: "errorHandling", format: "value", skipDefault: "fail" },
13541
+ { key: "defaultValue", format: "value" }
13534
13542
  ];
13535
13543
  var RETRIEVE_RECORD_FIELDS = [
13536
13544
  { key: "retrievalMode", format: "json" },
@@ -13542,7 +13550,6 @@ var RETRIEVE_RECORD_FIELDS = [
13542
13550
  { key: "fieldsToExclude", format: "json" },
13543
13551
  { key: "availableFields", format: "value" },
13544
13552
  { key: "outputVariable", format: "json" },
13545
- { key: "fields", format: "value" },
13546
13553
  { key: "includeMetadata", format: "raw" },
13547
13554
  { key: "streamOutput", format: "raw" }
13548
13555
  ];
@@ -13587,7 +13594,6 @@ var VECTOR_SEARCH_FIELDS = [
13587
13594
  { key: "vectorStore", format: "json" },
13588
13595
  { key: "weaviateConfig", format: "value" },
13589
13596
  { key: "vectorizeConfig", format: "value" },
13590
- { key: "pineconeConfig", format: "value" },
13591
13597
  { key: "limit", format: "raw", skipDefault: 5 },
13592
13598
  { key: "threshold", format: "raw", skipDefault: 0.7 },
13593
13599
  { key: "metadataFilters", format: "value" },
@@ -13604,7 +13610,6 @@ var GENERATE_EMBEDDING_FIELDS = [
13604
13610
  { key: "recordType", format: "json" },
13605
13611
  { key: "recordName", format: "json" },
13606
13612
  { key: "textField", format: "json" },
13607
- { key: "storeInRecord", format: "raw" },
13608
13613
  { key: "embeddingModel", format: "json" },
13609
13614
  { key: "maxLength", format: "raw" },
13610
13615
  { key: "inputMode", format: "json" },
@@ -13612,7 +13617,6 @@ var GENERATE_EMBEDDING_FIELDS = [
13612
13617
  { key: "itemAlias", format: "json" },
13613
13618
  { key: "textTemplate", format: "template" },
13614
13619
  { key: "batchSize", format: "raw" },
13615
- { key: "vectorStore", format: "value" },
13616
13620
  { key: "outputVariable", format: "json" },
13617
13621
  { key: "streamOutput", format: "raw" }
13618
13622
  ];
@@ -13632,31 +13636,9 @@ var SEND_EVENT_FIELDS = [
13632
13636
  { key: "streamOutput", format: "raw" },
13633
13637
  { key: "errorHandling", format: "value", skipDefault: "fail" }
13634
13638
  ];
13635
- var SEND_TEXT_FIELDS = [
13636
- { key: "to", format: "json" },
13637
- { key: "from", format: "json" },
13638
- { key: "message", format: "template" },
13639
- { key: "outputVariable", format: "json" },
13640
- { key: "streamOutput", format: "raw" },
13641
- { key: "errorHandling", format: "value", skipDefault: "fail" }
13642
- ];
13643
- var FETCH_GITHUB_FIELDS = [
13644
- { key: "repository", format: "json" },
13645
- { key: "branch", format: "json" },
13646
- { key: "path", format: "json" },
13647
- { key: "token", format: "json" },
13648
- { key: "outputVariable", format: "json" },
13649
- { key: "contentType", format: "json" },
13650
- { key: "includePatterns", format: "value" },
13651
- { key: "excludePatterns", format: "value" },
13652
- { key: "compress", format: "raw" },
13653
- { key: "style", format: "json" },
13654
- { key: "streamOutput", format: "raw" }
13655
- ];
13656
13639
  var API_CALL_FIELDS = [
13657
13640
  { key: "http", format: "value" },
13658
13641
  { key: "auth", format: "value" },
13659
- { key: "requestTemplate", format: "template" },
13660
13642
  { key: "responseMapping", format: "value" },
13661
13643
  { key: "outputVariable", format: "json" },
13662
13644
  { key: "streamOutput", format: "raw" },
@@ -13667,7 +13649,6 @@ var EXECUTE_AGENT_FIELDS = [
13667
13649
  { key: "agentId", format: "json" },
13668
13650
  { key: "message", format: "template" },
13669
13651
  { key: "outputVariable", format: "json" },
13670
- { key: "variables", format: "value" },
13671
13652
  { key: "maxTurns", format: "raw" },
13672
13653
  { key: "timeout", format: "raw" },
13673
13654
  { key: "errorHandling", format: "value", skipDefault: "fail" },
@@ -13714,7 +13695,6 @@ var UPDATE_RECORD_FIELDS = [
13714
13695
  { key: "recordName", format: "json" },
13715
13696
  { key: "recordFilter", format: "value" },
13716
13697
  { key: "updates", format: "value" },
13717
- { key: "updatesTemplate", format: "template" },
13718
13698
  { key: "mergeStrategy", format: "json" },
13719
13699
  { key: "outputVariable", format: "json" },
13720
13700
  { key: "streamOutput", format: "raw" },
@@ -13751,7 +13731,6 @@ var PAGINATE_API_FIELDS = [
13751
13731
  { key: "startPage", format: "raw" },
13752
13732
  { key: "entitiesPath", format: "json" },
13753
13733
  { key: "entityPath", format: "json" },
13754
- { key: "entityIdPath", format: "json" },
13755
13734
  { key: "maxEntities", format: "raw" },
13756
13735
  { key: "requestDelayMs", format: "raw" },
13757
13736
  { key: "retryOnRateLimit", format: "raw" },
@@ -13771,13 +13750,10 @@ var STORE_VECTOR_FIELDS = [
13771
13750
  { key: "destination", format: "json" },
13772
13751
  { key: "weaviateConfig", format: "value" },
13773
13752
  { key: "vectorizeConfig", format: "value" },
13774
- { key: "pineconeConfig", format: "value" },
13775
13753
  { key: "weaviateConfigId", format: "json" },
13776
13754
  { key: "weaviateClassName", format: "json" },
13777
13755
  { key: "vectorizeConfigId", format: "json" },
13778
13756
  { key: "vectorizeNamespace", format: "json" },
13779
- { key: "pineconeConfigId", format: "json" },
13780
- { key: "pineconeNamespace", format: "json" },
13781
13757
  { key: "idTemplate", format: "template" },
13782
13758
  { key: "metadata", format: "value" },
13783
13759
  { key: "outputVariable", format: "json" },
@@ -13829,8 +13805,6 @@ var STEP_FIELD_REGISTRY = {
13829
13805
  "generate-embedding": GENERATE_EMBEDDING_FIELDS,
13830
13806
  "wait-until": WAIT_UNTIL_FIELDS,
13831
13807
  "send-event": SEND_EVENT_FIELDS,
13832
- "send-text": SEND_TEXT_FIELDS,
13833
- "fetch-github": FETCH_GITHUB_FIELDS,
13834
13808
  template: TEMPLATE_FIELDS,
13835
13809
  "store-asset": STORE_ASSET_FIELDS,
13836
13810
  "generate-pdf": GENERATE_PDF_FIELDS,
@@ -13850,7 +13824,6 @@ var STEP_TYPE_TO_METHOD = {
13850
13824
  "retrieve-record": "retrieveRecord",
13851
13825
  "get-record": "getRecord",
13852
13826
  "list-records": "listRecords",
13853
- "fetch-github": "fetchGitHub",
13854
13827
  "transform-data": "transformData",
13855
13828
  template: "template",
13856
13829
  conditional: "conditional",
@@ -13858,7 +13831,6 @@ var STEP_TYPE_TO_METHOD = {
13858
13831
  "upsert-record": "upsertRecord",
13859
13832
  "update-record": "updateRecord",
13860
13833
  "send-email": "sendEmail",
13861
- "send-text": "sendText",
13862
13834
  "send-event": "sendEvent",
13863
13835
  "send-stream": "sendStream",
13864
13836
  search: "search",
@@ -13883,7 +13855,6 @@ export {
13883
13855
  AgentsNamespace,
13884
13856
  AnalyticsEndpoint,
13885
13857
  ApiKeysEndpoint,
13886
- AppsEndpoint,
13887
13858
  BatchBuilder,
13888
13859
  BatchesNamespace,
13889
13860
  BillingEndpoint,
@@ -13892,6 +13863,7 @@ export {
13892
13863
  ClientEvalBuilder,
13893
13864
  ClientFlowBuilder,
13894
13865
  ClientTokensEndpoint,
13866
+ CollectionsEndpoint,
13895
13867
  ContextTemplatesEndpoint,
13896
13868
  ConversationsEndpoint,
13897
13869
  DEFAULT_RECOVERY_AFTER_EMPTY_SESSIONS,