@runtypelabs/sdk 9.12.0 → 9.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -20,8 +20,16 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
20
20
  // src/index.ts
21
21
  var index_exports = {};
22
22
  __export(index_exports, {
23
+ AgentAliasDependencyError: () => AgentAliasDependencyError,
24
+ AgentAliasNotFoundError: () => AgentAliasNotFoundError,
25
+ AgentAliasPreviewLimitError: () => AgentAliasPreviewLimitError,
26
+ AgentAliasRevisionMismatchError: () => AgentAliasRevisionMismatchError,
27
+ AgentAliasRevisionRequiredError: () => AgentAliasRevisionRequiredError,
28
+ AgentAliasesNamespace: () => AgentAliasesNamespace,
29
+ AgentDeploymentsNamespace: () => AgentDeploymentsNamespace,
23
30
  AgentDriftError: () => AgentDriftError,
24
31
  AgentEnsureConflictError: () => AgentEnsureConflictError,
32
+ AgentPromotionError: () => AgentPromotionError,
25
33
  AgentVersionsEndpoint: () => AgentVersionsEndpoint,
26
34
  AgentsEndpoint: () => AgentsEndpoint,
27
35
  AgentsNamespace: () => AgentsNamespace,
@@ -43,6 +51,7 @@ __export(index_exports, {
43
51
  DEFAULT_RECOVERY_AFTER_EMPTY_SESSIONS: () => DEFAULT_RECOVERY_AFTER_EMPTY_SESSIONS,
44
52
  DEFAULT_STALL_STOP_AFTER: () => DEFAULT_STALL_STOP_AFTER,
45
53
  DispatchEndpoint: () => DispatchEndpoint,
54
+ ENSURE_RELEASE_DEPLOY_CONFLICT_MESSAGE: () => ENSURE_RELEASE_DEPLOY_CONFLICT_MESSAGE,
46
55
  EvalBuilder: () => EvalBuilder,
47
56
  EvalEndpoint: () => EvalEndpoint,
48
57
  EvalRunner: () => EvalRunner,
@@ -60,6 +69,7 @@ __export(index_exports, {
60
69
  FlowsNamespace: () => FlowsNamespace,
61
70
  IntegrationsEndpoint: () => IntegrationsEndpoint,
62
71
  LEDGER_ARTIFACT_LINE_PREFIX: () => LEDGER_ARTIFACT_LINE_PREFIX,
72
+ LIVE_AGENT_ALIAS: () => LIVE_AGENT_ALIAS,
63
73
  LogsEndpoint: () => LogsEndpoint,
64
74
  ModelConfigsEndpoint: () => ModelConfigsEndpoint,
65
75
  ProductDriftError: () => ProductDriftError,
@@ -96,6 +106,8 @@ __export(index_exports, {
96
106
  TypedRecordsScope: () => TypedRecordsScope,
97
107
  UNIFIED_EVENTS_QUERY: () => UNIFIED_EVENTS_QUERY,
98
108
  UsersEndpoint: () => UsersEndpoint,
109
+ activateAgentPromotion: () => activateAgentPromotion,
110
+ agentAliasErrorCode: () => agentAliasErrorCode,
99
111
  applyGeneratedRuntimeToolProposalToDispatchRequest: () => applyGeneratedRuntimeToolProposalToDispatchRequest,
100
112
  attachRuntimeToolsToDispatchRequest: () => attachRuntimeToolsToDispatchRequest,
101
113
  buildAgentAdmissionHeaders: () => buildAgentAdmissionHeaders,
@@ -173,7 +185,10 @@ __export(index_exports, {
173
185
  parseLedgerArtifactRelativePath: () => parseLedgerArtifactRelativePath,
174
186
  parseOffloadedOutputId: () => parseOffloadedOutputId,
175
187
  parseSSEChunk: () => parseSSEChunk,
188
+ prepareAgentPromotion: () => prepareAgentPromotion,
176
189
  processStream: () => processStream,
190
+ promoteAgent: () => promoteAgent,
191
+ promotionIdempotencyKey: () => promotionIdempotencyKey,
177
192
  pullEval: () => pullEval,
178
193
  pullFpo: () => pullFpo,
179
194
  ranStep: () => ranStep,
@@ -191,6 +206,7 @@ __export(index_exports, {
191
206
  unregisterWorkflowHook: () => unregisterWorkflowHook,
192
207
  usedNoTools: () => usedNoTools,
193
208
  validJson: () => validJson,
209
+ validateAgentPromotion: () => validateAgentPromotion,
194
210
  withDetachedReconnect: () => withDetachedReconnect,
195
211
  withUnifiedEvents: () => withUnifiedEvents
196
212
  });
@@ -2251,6 +2267,268 @@ data: ${JSON.stringify({
2251
2267
  });
2252
2268
  }
2253
2269
 
2270
+ // src/agent-aliases-namespace.ts
2271
+ var LIVE_AGENT_ALIAS = "live";
2272
+ var AgentAliasRevisionMismatchError = class extends Error {
2273
+ constructor(body) {
2274
+ super(
2275
+ body.error ?? `Alias revision mismatch: expected ${body.expected}, found ${body.actual ?? "no alias"}.`
2276
+ );
2277
+ this.code = "alias_revision_mismatch";
2278
+ this.name = "AgentAliasRevisionMismatchError";
2279
+ this.expectedRevision = body.expected;
2280
+ this.actualRevision = body.actual;
2281
+ }
2282
+ };
2283
+ var AgentAliasRevisionRequiredError = class extends Error {
2284
+ constructor(message) {
2285
+ super(message);
2286
+ this.code = "alias_revision_required";
2287
+ this.name = "AgentAliasRevisionRequiredError";
2288
+ }
2289
+ };
2290
+ var AgentAliasNotFoundError = class extends Error {
2291
+ constructor(body) {
2292
+ super(body.error ?? `Alias "${body.alias}" was not found on agent ${body.agentId}.`);
2293
+ this.code = "alias_not_found";
2294
+ this.name = "AgentAliasNotFoundError";
2295
+ this.alias = body.alias;
2296
+ this.agentId = body.agentId;
2297
+ }
2298
+ };
2299
+ var AgentAliasPreviewLimitError = class extends Error {
2300
+ constructor(body) {
2301
+ super(
2302
+ body.error ?? `This ${body.scope} already has ${body.limit} active preview aliases, the maximum.`
2303
+ );
2304
+ this.code = "PREVIEW_ALIAS_LIMIT";
2305
+ this.name = "AgentAliasPreviewLimitError";
2306
+ this.scope = body.scope;
2307
+ this.limit = body.limit;
2308
+ this.active = body.active;
2309
+ }
2310
+ };
2311
+ var AgentAliasDependencyError = class extends Error {
2312
+ constructor(body) {
2313
+ super(body.error ?? "The version references a dependency that no longer resolves.");
2314
+ this.code = "alias_dependency_unresolved";
2315
+ this.name = "AgentAliasDependencyError";
2316
+ this.refs = body.refs ?? [];
2317
+ }
2318
+ };
2319
+ function asRecord(value) {
2320
+ return value !== null && typeof value === "object" && !Array.isArray(value) ? value : null;
2321
+ }
2322
+ function parseRequestError(err) {
2323
+ if (!(err instanceof Error)) return { status: null, body: null };
2324
+ const structured = err;
2325
+ if (typeof structured.statusCode === "number") {
2326
+ return { status: structured.statusCode, body: asRecord(structured.data) };
2327
+ }
2328
+ const match = err.message.match(/^API request failed: (\d{3}) .*? - ([\s\S]*)$/);
2329
+ if (!match) return { status: null, body: null };
2330
+ try {
2331
+ return { status: Number(match[1]), body: asRecord(JSON.parse(match[2])) };
2332
+ } catch {
2333
+ return { status: Number(match[1]), body: null };
2334
+ }
2335
+ }
2336
+ function asString(value, fallback) {
2337
+ return typeof value === "string" ? value : fallback;
2338
+ }
2339
+ function toAliasError(err, agentId, alias) {
2340
+ const { status, body } = parseRequestError(err);
2341
+ if (status === null) return null;
2342
+ const error = body && typeof body.error === "string" ? body.error : void 0;
2343
+ if (status === 412 && body && typeof body.expected === "number") {
2344
+ return new AgentAliasRevisionMismatchError({
2345
+ ...error !== void 0 ? { error } : {},
2346
+ expected: body.expected,
2347
+ actual: typeof body.actual === "number" ? body.actual : null
2348
+ });
2349
+ }
2350
+ if (status === 428) {
2351
+ return new AgentAliasRevisionRequiredError(
2352
+ error ?? "Updating an existing live alias requires an If-Match revision."
2353
+ );
2354
+ }
2355
+ if (status === 404 && body?.code === "alias_not_found") {
2356
+ return new AgentAliasNotFoundError({
2357
+ ...error !== void 0 ? { error } : {},
2358
+ alias: asString(body.alias, alias),
2359
+ agentId: asString(body.agentId, agentId)
2360
+ });
2361
+ }
2362
+ if (status === 429 && body?.code === "PREVIEW_ALIAS_LIMIT") {
2363
+ return new AgentAliasPreviewLimitError({
2364
+ ...error !== void 0 ? { error } : {},
2365
+ scope: body.scope === "organization" ? "organization" : "agent",
2366
+ limit: typeof body.limit === "number" ? body.limit : 0,
2367
+ active: typeof body.active === "number" ? body.active : 0
2368
+ });
2369
+ }
2370
+ if (status === 422 && body?.code === "alias_dependency_unresolved") {
2371
+ return new AgentAliasDependencyError({
2372
+ ...error !== void 0 ? { error } : {},
2373
+ refs: Array.isArray(body.refs) ? body.refs.filter((ref) => typeof ref === "string") : []
2374
+ });
2375
+ }
2376
+ return null;
2377
+ }
2378
+ var TYPED_ALIAS_ERRORS = [
2379
+ AgentAliasRevisionMismatchError,
2380
+ AgentAliasRevisionRequiredError,
2381
+ AgentAliasNotFoundError,
2382
+ AgentAliasDependencyError,
2383
+ AgentAliasPreviewLimitError
2384
+ ];
2385
+ function agentAliasErrorCode(err) {
2386
+ return TYPED_ALIAS_ERRORS.some((typed) => err instanceof typed) ? err.code : void 0;
2387
+ }
2388
+ function writeHeaders(input) {
2389
+ const headers = {};
2390
+ if (typeof input.revision === "number") headers["If-Match"] = String(input.revision);
2391
+ if (input.idempotencyKey) headers["Idempotency-Key"] = input.idempotencyKey;
2392
+ return headers;
2393
+ }
2394
+ function encode(value) {
2395
+ return encodeURIComponent(value);
2396
+ }
2397
+ var AgentAliasesNamespace = class {
2398
+ constructor(getTransport) {
2399
+ this.getTransport = getTransport;
2400
+ }
2401
+ /** List this agent's pointers, `live` first then previews by name. */
2402
+ async list(agentId, options = {}) {
2403
+ return this.getTransport().get(`/agents/${encode(agentId)}/aliases`, {
2404
+ ...options.includeArchived ? { includeArchived: "true" } : {},
2405
+ ...options.limit !== void 0 ? { limit: String(options.limit) } : {},
2406
+ ...options.cursor ? { cursor: options.cursor } : {}
2407
+ });
2408
+ }
2409
+ /**
2410
+ * Every agent in the organization carrying a pointer with this name, each
2411
+ * with the revision to quote back as `If-Match`. The read a PR-close cleanup
2412
+ * makes before archiving.
2413
+ */
2414
+ async listByName(alias, options = {}) {
2415
+ return this.getTransport().get("/agent-aliases", {
2416
+ alias,
2417
+ ...options.includeArchived ? { includeArchived: "true" } : {}
2418
+ });
2419
+ }
2420
+ /**
2421
+ * Archive this pointer on every agent in the organization that carries it,
2422
+ * each under the revision just read. A failure on one agent is reported and
2423
+ * the rest continue; a second run finds nothing active and archives nothing.
2424
+ */
2425
+ async archiveEverywhere(alias) {
2426
+ const listed = await this.listByName(alias);
2427
+ const rows = listed.data ?? [];
2428
+ const result = { alias, archived: [], failed: [] };
2429
+ for (const row of rows) {
2430
+ try {
2431
+ const archived = await this.archive(row.agentId, alias, { revision: row.revision });
2432
+ result.archived.push({
2433
+ agentId: row.agentId,
2434
+ agentName: row.agentName,
2435
+ revision: archived.revision,
2436
+ receiptId: archived.receiptId
2437
+ });
2438
+ } catch (err) {
2439
+ const code = agentAliasErrorCode(err);
2440
+ result.failed.push({
2441
+ agentId: row.agentId,
2442
+ agentName: row.agentName,
2443
+ error: err instanceof Error ? err.message : String(err),
2444
+ ...code ? { code } : {}
2445
+ });
2446
+ }
2447
+ }
2448
+ return result;
2449
+ }
2450
+ /** Read one pointer. A missing or archived alias throws, never falls back to live. */
2451
+ async get(agentId, alias, options = {}) {
2452
+ return this.run(
2453
+ agentId,
2454
+ alias,
2455
+ () => this.getTransport().get(`/agents/${encode(agentId)}/aliases/${encode(alias)}`, {
2456
+ ...options.includeArchived ? { includeArchived: "true" } : {}
2457
+ })
2458
+ );
2459
+ }
2460
+ /** Aim one pointer at one exact version, appending a deployment receipt. */
2461
+ async activate(agentId, alias, input) {
2462
+ const body = {
2463
+ versionId: input.versionId,
2464
+ ...input.reason ? { reason: input.reason } : {},
2465
+ ...input.promotion ? { promotion: input.promotion } : {}
2466
+ };
2467
+ return this.run(
2468
+ agentId,
2469
+ alias,
2470
+ () => this.getTransport().put(
2471
+ `/agents/${encode(agentId)}/aliases/${encode(alias)}`,
2472
+ body,
2473
+ writeHeaders(input)
2474
+ )
2475
+ );
2476
+ }
2477
+ /** Archive a preview pointer: it stops resolving but keeps its history. */
2478
+ async archive(agentId, alias, input = {}) {
2479
+ return this.run(
2480
+ agentId,
2481
+ alias,
2482
+ () => this.getTransport().delete(
2483
+ `/agents/${encode(agentId)}/aliases/${encode(alias)}`,
2484
+ void 0,
2485
+ writeHeaders(input)
2486
+ )
2487
+ );
2488
+ }
2489
+ /** Re-aim a pointer at the version its receipt history records before this one. */
2490
+ async rollback(agentId, alias, input = {}) {
2491
+ const body = {
2492
+ ...input.steps !== void 0 ? { steps: input.steps } : {},
2493
+ ...input.reason ? { reason: input.reason } : {}
2494
+ };
2495
+ return this.run(
2496
+ agentId,
2497
+ alias,
2498
+ () => this.getTransport().post(
2499
+ `/agents/${encode(agentId)}/aliases/${encode(alias)}/rollback`,
2500
+ body,
2501
+ writeHeaders(input)
2502
+ )
2503
+ );
2504
+ }
2505
+ async run(agentId, alias, call) {
2506
+ try {
2507
+ return await call();
2508
+ } catch (err) {
2509
+ const typed = toAliasError(err, agentId, alias);
2510
+ if (typed) throw typed;
2511
+ throw err;
2512
+ }
2513
+ }
2514
+ };
2515
+ var AgentDeploymentsNamespace = class {
2516
+ constructor(getTransport) {
2517
+ this.getTransport = getTransport;
2518
+ }
2519
+ /** Receipts newest first, cursor-paginated; filter to one pointer with `alias`. */
2520
+ async list(agentId, options = {}) {
2521
+ return this.getTransport().get(
2522
+ `/agents/${encode(agentId)}/deployments`,
2523
+ {
2524
+ ...options.alias ? { alias: options.alias } : {},
2525
+ ...options.limit !== void 0 ? { limit: String(options.limit) } : {},
2526
+ ...options.cursor ? { cursor: options.cursor } : {}
2527
+ }
2528
+ );
2529
+ }
2530
+ };
2531
+
2254
2532
  // src/generated-tool-gate.ts
2255
2533
  var TOOL_NAME_PATTERN = /^[A-Za-z][A-Za-z0-9_]{1,63}$/;
2256
2534
  var DEFAULT_MAX_CODE_LENGTH = 12e3;
@@ -2273,7 +2551,7 @@ var DEFAULT_ALLOWED_LANGUAGES = [
2273
2551
  function isObject(value) {
2274
2552
  return typeof value === "object" && value !== null && !Array.isArray(value);
2275
2553
  }
2276
- function asString(value) {
2554
+ function asString2(value) {
2277
2555
  return typeof value === "string" ? value.trim() : void 0;
2278
2556
  }
2279
2557
  function asNumber(value) {
@@ -2306,8 +2584,8 @@ function normalizeGeneratedProposal(proposal, violations) {
2306
2584
  violations.push("Generated tool proposal must be an object");
2307
2585
  return null;
2308
2586
  }
2309
- const name = asString(candidate.name);
2310
- const description = asString(candidate.description);
2587
+ const name = asString2(candidate.name);
2588
+ const description = asString2(candidate.description);
2311
2589
  const toolType = candidate.toolType;
2312
2590
  const parametersSchema = candidate.parametersSchema;
2313
2591
  if (!name) {
@@ -2342,7 +2620,7 @@ function normalizeGeneratedProposal(proposal, violations) {
2342
2620
  violations.push("Custom tool config is required");
2343
2621
  return null;
2344
2622
  }
2345
- const code = asString(config.code);
2623
+ const code = asString2(config.code);
2346
2624
  if (!code) {
2347
2625
  violations.push("Custom tool config.code is required");
2348
2626
  return null;
@@ -5819,6 +6097,8 @@ var _AgentsEndpoint = class _AgentsEndpoint {
5819
6097
  constructor(client) {
5820
6098
  this.client = client;
5821
6099
  this.TOOL_OUTPUT_INLINE_THRESHOLD = 500;
6100
+ this.aliases = new AgentAliasesNamespace(() => this.client);
6101
+ this.deployments = new AgentDeploymentsNamespace(() => this.client);
5822
6102
  }
5823
6103
  /**
5824
6104
  * List all agents for the authenticated user
@@ -9879,7 +10159,7 @@ var FlowDriftError = class extends Error {
9879
10159
  this.plan = plan;
9880
10160
  }
9881
10161
  };
9882
- function parseRequestError(err) {
10162
+ function parseRequestError2(err) {
9883
10163
  if (!(err instanceof Error)) return { status: null, body: null };
9884
10164
  const match = err.message.match(/^API request failed: (\d{3}) .*? - ([\s\S]*)$/);
9885
10165
  if (!match) return { status: null, body: null };
@@ -9890,7 +10170,7 @@ function parseRequestError(err) {
9890
10170
  }
9891
10171
  }
9892
10172
  function toConflictError(err) {
9893
- const { status, body } = parseRequestError(err);
10173
+ const { status, body } = parseRequestError2(err);
9894
10174
  if (status !== 409 || !isPlainObject(body)) return null;
9895
10175
  const code = body.code;
9896
10176
  if (code !== "external_modification" && code !== "remote_changed") return null;
@@ -11695,7 +11975,7 @@ var SkillDriftError = class extends Error {
11695
11975
  this.plan = plan;
11696
11976
  }
11697
11977
  };
11698
- function parseRequestError2(err) {
11978
+ function parseRequestError3(err) {
11699
11979
  if (!(err instanceof Error)) return { status: null, body: null };
11700
11980
  const match = err.message.match(/^API request failed: (\d{3}) .*? - ([\s\S]*)$/);
11701
11981
  if (!match) return { status: null, body: null };
@@ -11706,7 +11986,7 @@ function parseRequestError2(err) {
11706
11986
  }
11707
11987
  }
11708
11988
  function toConflictError2(err) {
11709
- const { status, body } = parseRequestError2(err);
11989
+ const { status, body } = parseRequestError3(err);
11710
11990
  if (status !== 409 || !isPlainObject(body)) return null;
11711
11991
  const code = body.code;
11712
11992
  if (code !== "external_modification" && code !== "remote_changed") return null;
@@ -12015,6 +12295,7 @@ var SkillsNamespace = class {
12015
12295
  };
12016
12296
 
12017
12297
  // src/agents-namespace.ts
12298
+ var ENSURE_RELEASE_DEPLOY_CONFLICT_MESSAGE = 'Provide either release or deploy, not both. release is a compatibility input; use deploy: { alias: "live" } instead of release: "publish", and omit both to save without activating.';
12018
12299
  var AGENT_CONFIG_KEYS = [
12019
12300
  "contextManagement",
12020
12301
  "model",
@@ -12174,7 +12455,7 @@ var AgentDriftError = class extends Error {
12174
12455
  this.plan = plan;
12175
12456
  }
12176
12457
  };
12177
- function parseRequestError3(err) {
12458
+ function parseRequestError4(err) {
12178
12459
  if (!(err instanceof Error)) return { status: null, body: null };
12179
12460
  const match = err.message.match(/^API request failed: (\d{3}) .*? - ([\s\S]*)$/);
12180
12461
  if (!match) return { status: null, body: null };
@@ -12185,7 +12466,7 @@ function parseRequestError3(err) {
12185
12466
  }
12186
12467
  }
12187
12468
  function toConflictError3(err) {
12188
- const { status, body } = parseRequestError3(err);
12469
+ const { status, body } = parseRequestError4(err);
12189
12470
  if (status !== 409 || !isPlainObject2(body)) return null;
12190
12471
  const code = body.code;
12191
12472
  if (code !== "external_modification" && code !== "remote_changed") return null;
@@ -12205,6 +12486,9 @@ function memoFor4(client) {
12205
12486
  var AgentsNamespace = class {
12206
12487
  constructor(getClient) {
12207
12488
  this.getClient = getClient;
12489
+ const transport = () => this.getClient();
12490
+ this.aliases = new AgentAliasesNamespace(transport);
12491
+ this.deployments = new AgentDeploymentsNamespace(transport);
12208
12492
  }
12209
12493
  /**
12210
12494
  * Idempotently converge a definition onto the platform. Hash-first: probes
@@ -12214,10 +12498,14 @@ var AgentsNamespace = class {
12214
12498
  */
12215
12499
  async ensure(definition, options = {}) {
12216
12500
  const client = this.getClient();
12217
- const { dryRun, onConflict, release, expectedRemoteHash, version, expectNoChanges } = options;
12501
+ const { dryRun, onConflict, release, deploy, expectedRemoteHash, version, expectNoChanges } = options;
12502
+ if (release !== void 0 && deploy !== void 0) {
12503
+ throw new Error(ENSURE_RELEASE_DEPLOY_CONFLICT_MESSAGE);
12504
+ }
12218
12505
  const passthrough = {
12219
12506
  ...onConflict ? { onConflict } : {},
12220
12507
  ...release ? { release } : {},
12508
+ ...deploy ? { deploy } : {},
12221
12509
  ...expectedRemoteHash ? { expectedRemoteHash } : {},
12222
12510
  ...version ? { version } : {}
12223
12511
  };
@@ -12382,7 +12670,7 @@ var ToolDriftError = class extends Error {
12382
12670
  this.plan = plan;
12383
12671
  }
12384
12672
  };
12385
- function parseRequestError4(err) {
12673
+ function parseRequestError5(err) {
12386
12674
  if (!(err instanceof Error)) return { status: null, body: null };
12387
12675
  const match = err.message.match(/^API request failed: (\d{3}) .*? - ([\s\S]*)$/);
12388
12676
  if (!match) return { status: null, body: null };
@@ -12393,7 +12681,7 @@ function parseRequestError4(err) {
12393
12681
  }
12394
12682
  }
12395
12683
  function toConflictError4(err) {
12396
- const { status, body } = parseRequestError4(err);
12684
+ const { status, body } = parseRequestError5(err);
12397
12685
  if (status !== 409 || !isPlainObject(body)) return null;
12398
12686
  const code = body.code;
12399
12687
  if (code !== "external_modification" && code !== "remote_changed") return null;
@@ -12574,7 +12862,7 @@ var ProductDriftError = class extends Error {
12574
12862
  this.plan = plan;
12575
12863
  }
12576
12864
  };
12577
- function parseRequestError5(err) {
12865
+ function parseRequestError6(err) {
12578
12866
  if (!(err instanceof Error)) return { status: null, body: null };
12579
12867
  const match = err.message.match(/^API request failed: (\d{3}) .*? - ([\s\S]*)$/);
12580
12868
  if (!match) return { status: null, body: null };
@@ -12585,7 +12873,7 @@ function parseRequestError5(err) {
12585
12873
  }
12586
12874
  }
12587
12875
  function toConflictError5(err) {
12588
- const { status, body } = parseRequestError5(err);
12876
+ const { status, body } = parseRequestError6(err);
12589
12877
  if (status !== 409 || !isPlainObject(body)) return null;
12590
12878
  const code = body.code;
12591
12879
  if (code !== "external_modification" && code !== "remote_changed") return null;
@@ -12784,6 +13072,25 @@ var ProductsNamespace = class {
12784
13072
  async pullFpo(name) {
12785
13073
  return pullFpo(this.getClient(), name);
12786
13074
  }
13075
+ /**
13076
+ * One request for the first page of every activity source a product has:
13077
+ * conversations per conversational surface, executions per distinct agent.
13078
+ * Rows, cursors and `hasMore` match the per-source list endpoints, so a
13079
+ * caller continues any source with that source's own endpoint. A source that
13080
+ * fails carries an `error` instead of failing the response.
13081
+ *
13082
+ * @example
13083
+ * ```typescript
13084
+ * const { data } = await Runtype.products.activity('prd_123', { limit: 25 })
13085
+ * for (const surface of data.surfaces) console.log(surface.surfaceId, surface.data.length)
13086
+ * ```
13087
+ */
13088
+ async activity(productId, options = {}) {
13089
+ return this.getClient().get(
13090
+ `/products/${encodeURIComponent(productId)}/activity`,
13091
+ options.limit === void 0 ? void 0 : { limit: String(options.limit) }
13092
+ );
13093
+ }
12787
13094
  };
12788
13095
 
12789
13096
  // src/surfaces-ensure.ts
@@ -12884,7 +13191,7 @@ var SurfaceDriftError = class extends Error {
12884
13191
  this.plan = plan;
12885
13192
  }
12886
13193
  };
12887
- function parseRequestError6(err) {
13194
+ function parseRequestError7(err) {
12888
13195
  if (!(err instanceof Error)) return { status: null, body: null };
12889
13196
  const match = err.message.match(/^API request failed: (\d{3}) .*? - ([\s\S]*)$/);
12890
13197
  if (!match) return { status: null, body: null };
@@ -12895,7 +13202,7 @@ function parseRequestError6(err) {
12895
13202
  }
12896
13203
  }
12897
13204
  function toConflictError6(err) {
12898
- const { status, body } = parseRequestError6(err);
13205
+ const { status, body } = parseRequestError7(err);
12899
13206
  if (status !== 409 || !isPlainObject(body)) return null;
12900
13207
  const code = body.code;
12901
13208
  if (code !== "external_modification" && code !== "remote_changed") return null;
@@ -13067,11 +13374,11 @@ var RuntypeClient = class {
13067
13374
  /**
13068
13375
  * Generic PUT request
13069
13376
  */
13070
- async put(path, data) {
13377
+ async put(path, data, extraHeaders) {
13071
13378
  const url = this.buildUrl(path);
13072
13379
  const response = await this.makeRequest(url, {
13073
13380
  method: "PUT",
13074
- headers: this.headers,
13381
+ headers: { ...this.headers, ...extraHeaders },
13075
13382
  body: data ? JSON.stringify(data) : void 0
13076
13383
  });
13077
13384
  return response;
@@ -13091,11 +13398,12 @@ var RuntypeClient = class {
13091
13398
  /**
13092
13399
  * Generic DELETE request
13093
13400
  */
13094
- async delete(path) {
13401
+ async delete(path, data, extraHeaders) {
13095
13402
  const url = this.buildUrl(path);
13096
13403
  const response = await this.makeRequest(url, {
13097
13404
  method: "DELETE",
13098
- headers: this.headers
13405
+ headers: { ...this.headers, ...extraHeaders },
13406
+ body: data ? JSON.stringify(data) : void 0
13099
13407
  });
13100
13408
  return response;
13101
13409
  }
@@ -13548,6 +13856,180 @@ var Runtype = class {
13548
13856
  }
13549
13857
  };
13550
13858
 
13859
+ // src/agent-promotion.ts
13860
+ var MANIFEST_VERSION = 1;
13861
+ var RECEIPT_PAGE_SIZE = 50;
13862
+ var MAX_RECEIPT_PAGES = 20;
13863
+ var AgentPromotionError = class extends Error {
13864
+ constructor(message) {
13865
+ super(message);
13866
+ this.name = "AgentPromotionError";
13867
+ }
13868
+ };
13869
+ function assertManifest(manifest) {
13870
+ if (manifest?.manifest !== MANIFEST_VERSION) {
13871
+ throw new AgentPromotionError(
13872
+ `Unsupported promotion manifest version ${String(manifest?.manifest)}; expected ${MANIFEST_VERSION}.`
13873
+ );
13874
+ }
13875
+ }
13876
+ async function ensureInto(transport, body) {
13877
+ return transport.post("/agents/ensure", body);
13878
+ }
13879
+ async function prepareAgentPromotion(input) {
13880
+ if (input.alias === "live") {
13881
+ throw new AgentPromotionError(
13882
+ "prepare stages a candidate at a preview alias and never deploys: pass a non-live alias, then promote it with activate."
13883
+ );
13884
+ }
13885
+ const pulled = await input.source.get("/agents/pull", { name: input.name });
13886
+ const converged = await ensureInto(input.target, {
13887
+ name: input.name,
13888
+ definition: pulled.definition,
13889
+ deploy: { alias: input.alias },
13890
+ ...input.version ? { version: input.version } : {}
13891
+ });
13892
+ if (converged.result === "plan") {
13893
+ throw new AgentPromotionError("The target converge answered a plan; expected a write.");
13894
+ }
13895
+ const deployment = converged.deployment;
13896
+ if (!deployment?.versionId) {
13897
+ throw new AgentPromotionError(
13898
+ `The target converge did not stage a version at "${input.alias}"; nothing to promote.`
13899
+ );
13900
+ }
13901
+ return {
13902
+ manifest: MANIFEST_VERSION,
13903
+ name: input.name,
13904
+ createdAt: (/* @__PURE__ */ new Date()).toISOString(),
13905
+ source: {
13906
+ agentId: pulled.agentId,
13907
+ versionId: pulled.versionId,
13908
+ contentHash: pulled.contentHash,
13909
+ ...input.commit ? { commit: input.commit } : {}
13910
+ },
13911
+ target: {
13912
+ agentId: converged.agentId,
13913
+ versionId: deployment.versionId,
13914
+ alias: deployment.alias,
13915
+ revision: deployment.revision,
13916
+ contentHash: converged.contentHash
13917
+ }
13918
+ };
13919
+ }
13920
+ async function validateAgentPromotion(input) {
13921
+ assertManifest(input.manifest);
13922
+ const definition = input.definition ?? await repullStagedDefinition({
13923
+ ...input.source ? { source: input.source } : {},
13924
+ manifest: input.manifest
13925
+ });
13926
+ const planned = await ensureInto(input.target, {
13927
+ name: input.manifest.name,
13928
+ definition,
13929
+ dryRun: true,
13930
+ deploy: { alias: input.manifest.target.alias }
13931
+ });
13932
+ if (planned.result !== "plan") {
13933
+ throw new AgentPromotionError(`Expected a plan from the dry run, got '${planned.result}'.`);
13934
+ }
13935
+ const staged = await findStagedReceipt(input.target, input.manifest);
13936
+ if (!staged) {
13937
+ throw new AgentPromotionError(
13938
+ `No deployment receipt for version ${input.manifest.target.versionId} at "${input.manifest.target.alias}" on agent ${input.manifest.target.agentId}. The staged candidate is gone, so there is nothing to validate; re-run prepare.`
13939
+ );
13940
+ }
13941
+ const refs = readReceiptRefs(staged);
13942
+ const unresolvedRefs = refs.filter((ref) => ref.resolvedId === null).map((ref) => ref.ref);
13943
+ return { ok: unresolvedRefs.length === 0, plan: planned, unresolvedRefs, refs };
13944
+ }
13945
+ async function repullStagedDefinition(input) {
13946
+ if (!input.source) {
13947
+ throw new AgentPromotionError(
13948
+ "validate needs the definition it planned: pass definition, or pass source credentials to re-pull it."
13949
+ );
13950
+ }
13951
+ const { name } = input.manifest;
13952
+ const pulled = await input.source.get("/agents/pull", { name });
13953
+ if (pulled.contentHash !== input.manifest.source.contentHash) {
13954
+ throw new AgentPromotionError(
13955
+ `The source definition changed since this promotion was prepared: the manifest was staged from ${input.manifest.source.contentHash}, and "${name}" now hashes to ${pulled.contentHash}. Re-run prepare so the artifact you validate is the one you staged.`
13956
+ );
13957
+ }
13958
+ return pulled.definition;
13959
+ }
13960
+ async function findStagedReceipt(target, manifest) {
13961
+ const deployments = new AgentDeploymentsNamespace(() => target);
13962
+ let cursor;
13963
+ for (let page = 0; page < MAX_RECEIPT_PAGES; page += 1) {
13964
+ const answered = await deployments.list(manifest.target.agentId, {
13965
+ alias: manifest.target.alias,
13966
+ limit: RECEIPT_PAGE_SIZE,
13967
+ ...cursor ? { cursor } : {}
13968
+ });
13969
+ const found = answered.data.find(
13970
+ (receipt) => receipt.versionId === manifest.target.versionId
13971
+ );
13972
+ if (found) return found;
13973
+ const next = answered.pagination?.nextCursor;
13974
+ if (typeof next !== "string" || next.length === 0) return null;
13975
+ cursor = next;
13976
+ }
13977
+ return null;
13978
+ }
13979
+ function readReceiptRefs(receipt) {
13980
+ const dependencies = receipt?.dependencies;
13981
+ const refs = dependencies?.refs;
13982
+ if (!Array.isArray(refs)) return [];
13983
+ return refs.flatMap((entry) => {
13984
+ if (entry === null || typeof entry !== "object") return [];
13985
+ const row = entry;
13986
+ if (typeof row.ref !== "string") return [];
13987
+ return [
13988
+ {
13989
+ ref: row.ref,
13990
+ resolvedId: typeof row.resolvedId === "string" ? row.resolvedId : null,
13991
+ fingerprint: typeof row.fingerprint === "string" ? row.fingerprint : null
13992
+ }
13993
+ ];
13994
+ });
13995
+ }
13996
+ async function activateAgentPromotion(input) {
13997
+ assertManifest(input.manifest);
13998
+ const alias = input.alias ?? "live";
13999
+ const aliases = new AgentAliasesNamespace(() => input.target);
14000
+ const current = await aliases.get(input.manifest.target.agentId, alias).catch((error) => {
14001
+ if (error instanceof AgentAliasNotFoundError) return null;
14002
+ throw error;
14003
+ });
14004
+ return aliases.activate(input.manifest.target.agentId, alias, {
14005
+ versionId: input.manifest.target.versionId,
14006
+ ...current ? { revision: current.revision } : {},
14007
+ idempotencyKey: input.idempotencyKey ?? promotionIdempotencyKey(input.manifest, alias),
14008
+ ...input.reason ? { reason: input.reason } : {},
14009
+ promotion: {
14010
+ sourceAgentId: input.manifest.source.agentId,
14011
+ ...input.manifest.source.versionId ? { sourceVersionId: input.manifest.source.versionId } : {},
14012
+ sourceContentHash: input.manifest.source.contentHash,
14013
+ ...input.manifest.source.commit ? { sourceCommit: input.manifest.source.commit } : {}
14014
+ }
14015
+ });
14016
+ }
14017
+ function promotionIdempotencyKey(manifest, alias) {
14018
+ return `promote:${manifest.target.agentId}:${alias}:${manifest.target.versionId}`;
14019
+ }
14020
+ async function promoteAgent(input) {
14021
+ const manifest = await prepareAgentPromotion(input);
14022
+ const definition = await repullStagedDefinition({ source: input.source, manifest });
14023
+ const validation = await validateAgentPromotion({ target: input.target, manifest, definition });
14024
+ if (!input.activate) return { manifest, validation };
14025
+ const activation = await activateAgentPromotion({
14026
+ target: input.target,
14027
+ manifest,
14028
+ ...input.activate
14029
+ });
14030
+ return { manifest, validation, activation };
14031
+ }
14032
+
13551
14033
  // src/transform.ts
13552
14034
  function transformQueryParams(params) {
13553
14035
  const result = {};
@@ -13565,7 +14047,7 @@ function transformQueryParams(params) {
13565
14047
 
13566
14048
  // src/version.ts
13567
14049
  var FALLBACK_VERSION = "0.0.0";
13568
- var SDK_VERSION = "9.12.0".length > 0 ? "9.12.0" : FALLBACK_VERSION;
14050
+ var SDK_VERSION = "9.13.0".length > 0 ? "9.13.0" : FALLBACK_VERSION;
13569
14051
  var RUNTYPE_CLIENT_KIND = "sdk";
13570
14052
  var SDK_USER_AGENT = `runtype-sdk/${SDK_VERSION} (typescript)`;
13571
14053
 
@@ -13944,11 +14426,11 @@ var RuntypeClient2 = class {
13944
14426
  /**
13945
14427
  * Generic PUT request
13946
14428
  */
13947
- async put(path, data) {
14429
+ async put(path, data, extraHeaders) {
13948
14430
  const url = this.buildUrl(path);
13949
14431
  const response = await this.makeRequest(url, {
13950
14432
  method: "PUT",
13951
- headers: this.headers,
14433
+ headers: { ...this.headers, ...extraHeaders },
13952
14434
  body: data ? JSON.stringify(data) : void 0
13953
14435
  });
13954
14436
  return response;
@@ -13968,11 +14450,11 @@ var RuntypeClient2 = class {
13968
14450
  /**
13969
14451
  * Generic DELETE request
13970
14452
  */
13971
- async delete(path, data) {
14453
+ async delete(path, data, extraHeaders) {
13972
14454
  const url = this.buildUrl(path);
13973
14455
  const response = await this.makeRequest(url, {
13974
14456
  method: "DELETE",
13975
- headers: this.headers,
14457
+ headers: { ...this.headers, ...extraHeaders },
13976
14458
  body: data ? JSON.stringify(data) : void 0
13977
14459
  });
13978
14460
  return response;
@@ -14834,8 +15316,16 @@ var STEP_TYPE_TO_METHOD = {
14834
15316
  };
14835
15317
  // Annotate the CommonJS export names for ESM import in node:
14836
15318
  0 && (module.exports = {
15319
+ AgentAliasDependencyError,
15320
+ AgentAliasNotFoundError,
15321
+ AgentAliasPreviewLimitError,
15322
+ AgentAliasRevisionMismatchError,
15323
+ AgentAliasRevisionRequiredError,
15324
+ AgentAliasesNamespace,
15325
+ AgentDeploymentsNamespace,
14837
15326
  AgentDriftError,
14838
15327
  AgentEnsureConflictError,
15328
+ AgentPromotionError,
14839
15329
  AgentVersionsEndpoint,
14840
15330
  AgentsEndpoint,
14841
15331
  AgentsNamespace,
@@ -14857,6 +15347,7 @@ var STEP_TYPE_TO_METHOD = {
14857
15347
  DEFAULT_RECOVERY_AFTER_EMPTY_SESSIONS,
14858
15348
  DEFAULT_STALL_STOP_AFTER,
14859
15349
  DispatchEndpoint,
15350
+ ENSURE_RELEASE_DEPLOY_CONFLICT_MESSAGE,
14860
15351
  EvalBuilder,
14861
15352
  EvalEndpoint,
14862
15353
  EvalRunner,
@@ -14874,6 +15365,7 @@ var STEP_TYPE_TO_METHOD = {
14874
15365
  FlowsNamespace,
14875
15366
  IntegrationsEndpoint,
14876
15367
  LEDGER_ARTIFACT_LINE_PREFIX,
15368
+ LIVE_AGENT_ALIAS,
14877
15369
  LogsEndpoint,
14878
15370
  ModelConfigsEndpoint,
14879
15371
  ProductDriftError,
@@ -14910,6 +15402,8 @@ var STEP_TYPE_TO_METHOD = {
14910
15402
  TypedRecordsScope,
14911
15403
  UNIFIED_EVENTS_QUERY,
14912
15404
  UsersEndpoint,
15405
+ activateAgentPromotion,
15406
+ agentAliasErrorCode,
14913
15407
  applyGeneratedRuntimeToolProposalToDispatchRequest,
14914
15408
  attachRuntimeToolsToDispatchRequest,
14915
15409
  buildAgentAdmissionHeaders,
@@ -14987,7 +15481,10 @@ var STEP_TYPE_TO_METHOD = {
14987
15481
  parseLedgerArtifactRelativePath,
14988
15482
  parseOffloadedOutputId,
14989
15483
  parseSSEChunk,
15484
+ prepareAgentPromotion,
14990
15485
  processStream,
15486
+ promoteAgent,
15487
+ promotionIdempotencyKey,
14991
15488
  pullEval,
14992
15489
  pullFpo,
14993
15490
  ranStep,
@@ -15005,6 +15502,7 @@ var STEP_TYPE_TO_METHOD = {
15005
15502
  unregisterWorkflowHook,
15006
15503
  usedNoTools,
15007
15504
  validJson,
15505
+ validateAgentPromotion,
15008
15506
  withDetachedReconnect,
15009
15507
  withUnifiedEvents
15010
15508
  });