@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.mjs CHANGED
@@ -2053,6 +2053,268 @@ data: ${JSON.stringify({
2053
2053
  });
2054
2054
  }
2055
2055
 
2056
+ // src/agent-aliases-namespace.ts
2057
+ var LIVE_AGENT_ALIAS = "live";
2058
+ var AgentAliasRevisionMismatchError = class extends Error {
2059
+ constructor(body) {
2060
+ super(
2061
+ body.error ?? `Alias revision mismatch: expected ${body.expected}, found ${body.actual ?? "no alias"}.`
2062
+ );
2063
+ this.code = "alias_revision_mismatch";
2064
+ this.name = "AgentAliasRevisionMismatchError";
2065
+ this.expectedRevision = body.expected;
2066
+ this.actualRevision = body.actual;
2067
+ }
2068
+ };
2069
+ var AgentAliasRevisionRequiredError = class extends Error {
2070
+ constructor(message) {
2071
+ super(message);
2072
+ this.code = "alias_revision_required";
2073
+ this.name = "AgentAliasRevisionRequiredError";
2074
+ }
2075
+ };
2076
+ var AgentAliasNotFoundError = class extends Error {
2077
+ constructor(body) {
2078
+ super(body.error ?? `Alias "${body.alias}" was not found on agent ${body.agentId}.`);
2079
+ this.code = "alias_not_found";
2080
+ this.name = "AgentAliasNotFoundError";
2081
+ this.alias = body.alias;
2082
+ this.agentId = body.agentId;
2083
+ }
2084
+ };
2085
+ var AgentAliasPreviewLimitError = class extends Error {
2086
+ constructor(body) {
2087
+ super(
2088
+ body.error ?? `This ${body.scope} already has ${body.limit} active preview aliases, the maximum.`
2089
+ );
2090
+ this.code = "PREVIEW_ALIAS_LIMIT";
2091
+ this.name = "AgentAliasPreviewLimitError";
2092
+ this.scope = body.scope;
2093
+ this.limit = body.limit;
2094
+ this.active = body.active;
2095
+ }
2096
+ };
2097
+ var AgentAliasDependencyError = class extends Error {
2098
+ constructor(body) {
2099
+ super(body.error ?? "The version references a dependency that no longer resolves.");
2100
+ this.code = "alias_dependency_unresolved";
2101
+ this.name = "AgentAliasDependencyError";
2102
+ this.refs = body.refs ?? [];
2103
+ }
2104
+ };
2105
+ function asRecord(value) {
2106
+ return value !== null && typeof value === "object" && !Array.isArray(value) ? value : null;
2107
+ }
2108
+ function parseRequestError(err) {
2109
+ if (!(err instanceof Error)) return { status: null, body: null };
2110
+ const structured = err;
2111
+ if (typeof structured.statusCode === "number") {
2112
+ return { status: structured.statusCode, body: asRecord(structured.data) };
2113
+ }
2114
+ const match = err.message.match(/^API request failed: (\d{3}) .*? - ([\s\S]*)$/);
2115
+ if (!match) return { status: null, body: null };
2116
+ try {
2117
+ return { status: Number(match[1]), body: asRecord(JSON.parse(match[2])) };
2118
+ } catch {
2119
+ return { status: Number(match[1]), body: null };
2120
+ }
2121
+ }
2122
+ function asString(value, fallback) {
2123
+ return typeof value === "string" ? value : fallback;
2124
+ }
2125
+ function toAliasError(err, agentId, alias) {
2126
+ const { status, body } = parseRequestError(err);
2127
+ if (status === null) return null;
2128
+ const error = body && typeof body.error === "string" ? body.error : void 0;
2129
+ if (status === 412 && body && typeof body.expected === "number") {
2130
+ return new AgentAliasRevisionMismatchError({
2131
+ ...error !== void 0 ? { error } : {},
2132
+ expected: body.expected,
2133
+ actual: typeof body.actual === "number" ? body.actual : null
2134
+ });
2135
+ }
2136
+ if (status === 428) {
2137
+ return new AgentAliasRevisionRequiredError(
2138
+ error ?? "Updating an existing live alias requires an If-Match revision."
2139
+ );
2140
+ }
2141
+ if (status === 404 && body?.code === "alias_not_found") {
2142
+ return new AgentAliasNotFoundError({
2143
+ ...error !== void 0 ? { error } : {},
2144
+ alias: asString(body.alias, alias),
2145
+ agentId: asString(body.agentId, agentId)
2146
+ });
2147
+ }
2148
+ if (status === 429 && body?.code === "PREVIEW_ALIAS_LIMIT") {
2149
+ return new AgentAliasPreviewLimitError({
2150
+ ...error !== void 0 ? { error } : {},
2151
+ scope: body.scope === "organization" ? "organization" : "agent",
2152
+ limit: typeof body.limit === "number" ? body.limit : 0,
2153
+ active: typeof body.active === "number" ? body.active : 0
2154
+ });
2155
+ }
2156
+ if (status === 422 && body?.code === "alias_dependency_unresolved") {
2157
+ return new AgentAliasDependencyError({
2158
+ ...error !== void 0 ? { error } : {},
2159
+ refs: Array.isArray(body.refs) ? body.refs.filter((ref) => typeof ref === "string") : []
2160
+ });
2161
+ }
2162
+ return null;
2163
+ }
2164
+ var TYPED_ALIAS_ERRORS = [
2165
+ AgentAliasRevisionMismatchError,
2166
+ AgentAliasRevisionRequiredError,
2167
+ AgentAliasNotFoundError,
2168
+ AgentAliasDependencyError,
2169
+ AgentAliasPreviewLimitError
2170
+ ];
2171
+ function agentAliasErrorCode(err) {
2172
+ return TYPED_ALIAS_ERRORS.some((typed) => err instanceof typed) ? err.code : void 0;
2173
+ }
2174
+ function writeHeaders(input) {
2175
+ const headers = {};
2176
+ if (typeof input.revision === "number") headers["If-Match"] = String(input.revision);
2177
+ if (input.idempotencyKey) headers["Idempotency-Key"] = input.idempotencyKey;
2178
+ return headers;
2179
+ }
2180
+ function encode(value) {
2181
+ return encodeURIComponent(value);
2182
+ }
2183
+ var AgentAliasesNamespace = class {
2184
+ constructor(getTransport) {
2185
+ this.getTransport = getTransport;
2186
+ }
2187
+ /** List this agent's pointers, `live` first then previews by name. */
2188
+ async list(agentId, options = {}) {
2189
+ return this.getTransport().get(`/agents/${encode(agentId)}/aliases`, {
2190
+ ...options.includeArchived ? { includeArchived: "true" } : {},
2191
+ ...options.limit !== void 0 ? { limit: String(options.limit) } : {},
2192
+ ...options.cursor ? { cursor: options.cursor } : {}
2193
+ });
2194
+ }
2195
+ /**
2196
+ * Every agent in the organization carrying a pointer with this name, each
2197
+ * with the revision to quote back as `If-Match`. The read a PR-close cleanup
2198
+ * makes before archiving.
2199
+ */
2200
+ async listByName(alias, options = {}) {
2201
+ return this.getTransport().get("/agent-aliases", {
2202
+ alias,
2203
+ ...options.includeArchived ? { includeArchived: "true" } : {}
2204
+ });
2205
+ }
2206
+ /**
2207
+ * Archive this pointer on every agent in the organization that carries it,
2208
+ * each under the revision just read. A failure on one agent is reported and
2209
+ * the rest continue; a second run finds nothing active and archives nothing.
2210
+ */
2211
+ async archiveEverywhere(alias) {
2212
+ const listed = await this.listByName(alias);
2213
+ const rows = listed.data ?? [];
2214
+ const result = { alias, archived: [], failed: [] };
2215
+ for (const row of rows) {
2216
+ try {
2217
+ const archived = await this.archive(row.agentId, alias, { revision: row.revision });
2218
+ result.archived.push({
2219
+ agentId: row.agentId,
2220
+ agentName: row.agentName,
2221
+ revision: archived.revision,
2222
+ receiptId: archived.receiptId
2223
+ });
2224
+ } catch (err) {
2225
+ const code = agentAliasErrorCode(err);
2226
+ result.failed.push({
2227
+ agentId: row.agentId,
2228
+ agentName: row.agentName,
2229
+ error: err instanceof Error ? err.message : String(err),
2230
+ ...code ? { code } : {}
2231
+ });
2232
+ }
2233
+ }
2234
+ return result;
2235
+ }
2236
+ /** Read one pointer. A missing or archived alias throws, never falls back to live. */
2237
+ async get(agentId, alias, options = {}) {
2238
+ return this.run(
2239
+ agentId,
2240
+ alias,
2241
+ () => this.getTransport().get(`/agents/${encode(agentId)}/aliases/${encode(alias)}`, {
2242
+ ...options.includeArchived ? { includeArchived: "true" } : {}
2243
+ })
2244
+ );
2245
+ }
2246
+ /** Aim one pointer at one exact version, appending a deployment receipt. */
2247
+ async activate(agentId, alias, input) {
2248
+ const body = {
2249
+ versionId: input.versionId,
2250
+ ...input.reason ? { reason: input.reason } : {},
2251
+ ...input.promotion ? { promotion: input.promotion } : {}
2252
+ };
2253
+ return this.run(
2254
+ agentId,
2255
+ alias,
2256
+ () => this.getTransport().put(
2257
+ `/agents/${encode(agentId)}/aliases/${encode(alias)}`,
2258
+ body,
2259
+ writeHeaders(input)
2260
+ )
2261
+ );
2262
+ }
2263
+ /** Archive a preview pointer: it stops resolving but keeps its history. */
2264
+ async archive(agentId, alias, input = {}) {
2265
+ return this.run(
2266
+ agentId,
2267
+ alias,
2268
+ () => this.getTransport().delete(
2269
+ `/agents/${encode(agentId)}/aliases/${encode(alias)}`,
2270
+ void 0,
2271
+ writeHeaders(input)
2272
+ )
2273
+ );
2274
+ }
2275
+ /** Re-aim a pointer at the version its receipt history records before this one. */
2276
+ async rollback(agentId, alias, input = {}) {
2277
+ const body = {
2278
+ ...input.steps !== void 0 ? { steps: input.steps } : {},
2279
+ ...input.reason ? { reason: input.reason } : {}
2280
+ };
2281
+ return this.run(
2282
+ agentId,
2283
+ alias,
2284
+ () => this.getTransport().post(
2285
+ `/agents/${encode(agentId)}/aliases/${encode(alias)}/rollback`,
2286
+ body,
2287
+ writeHeaders(input)
2288
+ )
2289
+ );
2290
+ }
2291
+ async run(agentId, alias, call) {
2292
+ try {
2293
+ return await call();
2294
+ } catch (err) {
2295
+ const typed = toAliasError(err, agentId, alias);
2296
+ if (typed) throw typed;
2297
+ throw err;
2298
+ }
2299
+ }
2300
+ };
2301
+ var AgentDeploymentsNamespace = class {
2302
+ constructor(getTransport) {
2303
+ this.getTransport = getTransport;
2304
+ }
2305
+ /** Receipts newest first, cursor-paginated; filter to one pointer with `alias`. */
2306
+ async list(agentId, options = {}) {
2307
+ return this.getTransport().get(
2308
+ `/agents/${encode(agentId)}/deployments`,
2309
+ {
2310
+ ...options.alias ? { alias: options.alias } : {},
2311
+ ...options.limit !== void 0 ? { limit: String(options.limit) } : {},
2312
+ ...options.cursor ? { cursor: options.cursor } : {}
2313
+ }
2314
+ );
2315
+ }
2316
+ };
2317
+
2056
2318
  // src/generated-tool-gate.ts
2057
2319
  var TOOL_NAME_PATTERN = /^[A-Za-z][A-Za-z0-9_]{1,63}$/;
2058
2320
  var DEFAULT_MAX_CODE_LENGTH = 12e3;
@@ -2075,7 +2337,7 @@ var DEFAULT_ALLOWED_LANGUAGES = [
2075
2337
  function isObject(value) {
2076
2338
  return typeof value === "object" && value !== null && !Array.isArray(value);
2077
2339
  }
2078
- function asString(value) {
2340
+ function asString2(value) {
2079
2341
  return typeof value === "string" ? value.trim() : void 0;
2080
2342
  }
2081
2343
  function asNumber(value) {
@@ -2108,8 +2370,8 @@ function normalizeGeneratedProposal(proposal, violations) {
2108
2370
  violations.push("Generated tool proposal must be an object");
2109
2371
  return null;
2110
2372
  }
2111
- const name = asString(candidate.name);
2112
- const description = asString(candidate.description);
2373
+ const name = asString2(candidate.name);
2374
+ const description = asString2(candidate.description);
2113
2375
  const toolType = candidate.toolType;
2114
2376
  const parametersSchema = candidate.parametersSchema;
2115
2377
  if (!name) {
@@ -2144,7 +2406,7 @@ function normalizeGeneratedProposal(proposal, violations) {
2144
2406
  violations.push("Custom tool config is required");
2145
2407
  return null;
2146
2408
  }
2147
- const code = asString(config.code);
2409
+ const code = asString2(config.code);
2148
2410
  if (!code) {
2149
2411
  violations.push("Custom tool config.code is required");
2150
2412
  return null;
@@ -5621,6 +5883,8 @@ var _AgentsEndpoint = class _AgentsEndpoint {
5621
5883
  constructor(client) {
5622
5884
  this.client = client;
5623
5885
  this.TOOL_OUTPUT_INLINE_THRESHOLD = 500;
5886
+ this.aliases = new AgentAliasesNamespace(() => this.client);
5887
+ this.deployments = new AgentDeploymentsNamespace(() => this.client);
5624
5888
  }
5625
5889
  /**
5626
5890
  * List all agents for the authenticated user
@@ -9681,7 +9945,7 @@ var FlowDriftError = class extends Error {
9681
9945
  this.plan = plan;
9682
9946
  }
9683
9947
  };
9684
- function parseRequestError(err) {
9948
+ function parseRequestError2(err) {
9685
9949
  if (!(err instanceof Error)) return { status: null, body: null };
9686
9950
  const match = err.message.match(/^API request failed: (\d{3}) .*? - ([\s\S]*)$/);
9687
9951
  if (!match) return { status: null, body: null };
@@ -9692,7 +9956,7 @@ function parseRequestError(err) {
9692
9956
  }
9693
9957
  }
9694
9958
  function toConflictError(err) {
9695
- const { status, body } = parseRequestError(err);
9959
+ const { status, body } = parseRequestError2(err);
9696
9960
  if (status !== 409 || !isPlainObject(body)) return null;
9697
9961
  const code = body.code;
9698
9962
  if (code !== "external_modification" && code !== "remote_changed") return null;
@@ -11497,7 +11761,7 @@ var SkillDriftError = class extends Error {
11497
11761
  this.plan = plan;
11498
11762
  }
11499
11763
  };
11500
- function parseRequestError2(err) {
11764
+ function parseRequestError3(err) {
11501
11765
  if (!(err instanceof Error)) return { status: null, body: null };
11502
11766
  const match = err.message.match(/^API request failed: (\d{3}) .*? - ([\s\S]*)$/);
11503
11767
  if (!match) return { status: null, body: null };
@@ -11508,7 +11772,7 @@ function parseRequestError2(err) {
11508
11772
  }
11509
11773
  }
11510
11774
  function toConflictError2(err) {
11511
- const { status, body } = parseRequestError2(err);
11775
+ const { status, body } = parseRequestError3(err);
11512
11776
  if (status !== 409 || !isPlainObject(body)) return null;
11513
11777
  const code = body.code;
11514
11778
  if (code !== "external_modification" && code !== "remote_changed") return null;
@@ -11817,6 +12081,7 @@ var SkillsNamespace = class {
11817
12081
  };
11818
12082
 
11819
12083
  // src/agents-namespace.ts
12084
+ 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.';
11820
12085
  var AGENT_CONFIG_KEYS = [
11821
12086
  "contextManagement",
11822
12087
  "model",
@@ -11976,7 +12241,7 @@ var AgentDriftError = class extends Error {
11976
12241
  this.plan = plan;
11977
12242
  }
11978
12243
  };
11979
- function parseRequestError3(err) {
12244
+ function parseRequestError4(err) {
11980
12245
  if (!(err instanceof Error)) return { status: null, body: null };
11981
12246
  const match = err.message.match(/^API request failed: (\d{3}) .*? - ([\s\S]*)$/);
11982
12247
  if (!match) return { status: null, body: null };
@@ -11987,7 +12252,7 @@ function parseRequestError3(err) {
11987
12252
  }
11988
12253
  }
11989
12254
  function toConflictError3(err) {
11990
- const { status, body } = parseRequestError3(err);
12255
+ const { status, body } = parseRequestError4(err);
11991
12256
  if (status !== 409 || !isPlainObject2(body)) return null;
11992
12257
  const code = body.code;
11993
12258
  if (code !== "external_modification" && code !== "remote_changed") return null;
@@ -12007,6 +12272,9 @@ function memoFor4(client) {
12007
12272
  var AgentsNamespace = class {
12008
12273
  constructor(getClient) {
12009
12274
  this.getClient = getClient;
12275
+ const transport = () => this.getClient();
12276
+ this.aliases = new AgentAliasesNamespace(transport);
12277
+ this.deployments = new AgentDeploymentsNamespace(transport);
12010
12278
  }
12011
12279
  /**
12012
12280
  * Idempotently converge a definition onto the platform. Hash-first: probes
@@ -12016,10 +12284,14 @@ var AgentsNamespace = class {
12016
12284
  */
12017
12285
  async ensure(definition, options = {}) {
12018
12286
  const client = this.getClient();
12019
- const { dryRun, onConflict, release, expectedRemoteHash, version, expectNoChanges } = options;
12287
+ const { dryRun, onConflict, release, deploy, expectedRemoteHash, version, expectNoChanges } = options;
12288
+ if (release !== void 0 && deploy !== void 0) {
12289
+ throw new Error(ENSURE_RELEASE_DEPLOY_CONFLICT_MESSAGE);
12290
+ }
12020
12291
  const passthrough = {
12021
12292
  ...onConflict ? { onConflict } : {},
12022
12293
  ...release ? { release } : {},
12294
+ ...deploy ? { deploy } : {},
12023
12295
  ...expectedRemoteHash ? { expectedRemoteHash } : {},
12024
12296
  ...version ? { version } : {}
12025
12297
  };
@@ -12184,7 +12456,7 @@ var ToolDriftError = class extends Error {
12184
12456
  this.plan = plan;
12185
12457
  }
12186
12458
  };
12187
- function parseRequestError4(err) {
12459
+ function parseRequestError5(err) {
12188
12460
  if (!(err instanceof Error)) return { status: null, body: null };
12189
12461
  const match = err.message.match(/^API request failed: (\d{3}) .*? - ([\s\S]*)$/);
12190
12462
  if (!match) return { status: null, body: null };
@@ -12195,7 +12467,7 @@ function parseRequestError4(err) {
12195
12467
  }
12196
12468
  }
12197
12469
  function toConflictError4(err) {
12198
- const { status, body } = parseRequestError4(err);
12470
+ const { status, body } = parseRequestError5(err);
12199
12471
  if (status !== 409 || !isPlainObject(body)) return null;
12200
12472
  const code = body.code;
12201
12473
  if (code !== "external_modification" && code !== "remote_changed") return null;
@@ -12376,7 +12648,7 @@ var ProductDriftError = class extends Error {
12376
12648
  this.plan = plan;
12377
12649
  }
12378
12650
  };
12379
- function parseRequestError5(err) {
12651
+ function parseRequestError6(err) {
12380
12652
  if (!(err instanceof Error)) return { status: null, body: null };
12381
12653
  const match = err.message.match(/^API request failed: (\d{3}) .*? - ([\s\S]*)$/);
12382
12654
  if (!match) return { status: null, body: null };
@@ -12387,7 +12659,7 @@ function parseRequestError5(err) {
12387
12659
  }
12388
12660
  }
12389
12661
  function toConflictError5(err) {
12390
- const { status, body } = parseRequestError5(err);
12662
+ const { status, body } = parseRequestError6(err);
12391
12663
  if (status !== 409 || !isPlainObject(body)) return null;
12392
12664
  const code = body.code;
12393
12665
  if (code !== "external_modification" && code !== "remote_changed") return null;
@@ -12586,6 +12858,25 @@ var ProductsNamespace = class {
12586
12858
  async pullFpo(name) {
12587
12859
  return pullFpo(this.getClient(), name);
12588
12860
  }
12861
+ /**
12862
+ * One request for the first page of every activity source a product has:
12863
+ * conversations per conversational surface, executions per distinct agent.
12864
+ * Rows, cursors and `hasMore` match the per-source list endpoints, so a
12865
+ * caller continues any source with that source's own endpoint. A source that
12866
+ * fails carries an `error` instead of failing the response.
12867
+ *
12868
+ * @example
12869
+ * ```typescript
12870
+ * const { data } = await Runtype.products.activity('prd_123', { limit: 25 })
12871
+ * for (const surface of data.surfaces) console.log(surface.surfaceId, surface.data.length)
12872
+ * ```
12873
+ */
12874
+ async activity(productId, options = {}) {
12875
+ return this.getClient().get(
12876
+ `/products/${encodeURIComponent(productId)}/activity`,
12877
+ options.limit === void 0 ? void 0 : { limit: String(options.limit) }
12878
+ );
12879
+ }
12589
12880
  };
12590
12881
 
12591
12882
  // src/surfaces-ensure.ts
@@ -12686,7 +12977,7 @@ var SurfaceDriftError = class extends Error {
12686
12977
  this.plan = plan;
12687
12978
  }
12688
12979
  };
12689
- function parseRequestError6(err) {
12980
+ function parseRequestError7(err) {
12690
12981
  if (!(err instanceof Error)) return { status: null, body: null };
12691
12982
  const match = err.message.match(/^API request failed: (\d{3}) .*? - ([\s\S]*)$/);
12692
12983
  if (!match) return { status: null, body: null };
@@ -12697,7 +12988,7 @@ function parseRequestError6(err) {
12697
12988
  }
12698
12989
  }
12699
12990
  function toConflictError6(err) {
12700
- const { status, body } = parseRequestError6(err);
12991
+ const { status, body } = parseRequestError7(err);
12701
12992
  if (status !== 409 || !isPlainObject(body)) return null;
12702
12993
  const code = body.code;
12703
12994
  if (code !== "external_modification" && code !== "remote_changed") return null;
@@ -12869,11 +13160,11 @@ var RuntypeClient = class {
12869
13160
  /**
12870
13161
  * Generic PUT request
12871
13162
  */
12872
- async put(path, data) {
13163
+ async put(path, data, extraHeaders) {
12873
13164
  const url = this.buildUrl(path);
12874
13165
  const response = await this.makeRequest(url, {
12875
13166
  method: "PUT",
12876
- headers: this.headers,
13167
+ headers: { ...this.headers, ...extraHeaders },
12877
13168
  body: data ? JSON.stringify(data) : void 0
12878
13169
  });
12879
13170
  return response;
@@ -12893,11 +13184,12 @@ var RuntypeClient = class {
12893
13184
  /**
12894
13185
  * Generic DELETE request
12895
13186
  */
12896
- async delete(path) {
13187
+ async delete(path, data, extraHeaders) {
12897
13188
  const url = this.buildUrl(path);
12898
13189
  const response = await this.makeRequest(url, {
12899
13190
  method: "DELETE",
12900
- headers: this.headers
13191
+ headers: { ...this.headers, ...extraHeaders },
13192
+ body: data ? JSON.stringify(data) : void 0
12901
13193
  });
12902
13194
  return response;
12903
13195
  }
@@ -13350,6 +13642,180 @@ var Runtype = class {
13350
13642
  }
13351
13643
  };
13352
13644
 
13645
+ // src/agent-promotion.ts
13646
+ var MANIFEST_VERSION = 1;
13647
+ var RECEIPT_PAGE_SIZE = 50;
13648
+ var MAX_RECEIPT_PAGES = 20;
13649
+ var AgentPromotionError = class extends Error {
13650
+ constructor(message) {
13651
+ super(message);
13652
+ this.name = "AgentPromotionError";
13653
+ }
13654
+ };
13655
+ function assertManifest(manifest) {
13656
+ if (manifest?.manifest !== MANIFEST_VERSION) {
13657
+ throw new AgentPromotionError(
13658
+ `Unsupported promotion manifest version ${String(manifest?.manifest)}; expected ${MANIFEST_VERSION}.`
13659
+ );
13660
+ }
13661
+ }
13662
+ async function ensureInto(transport, body) {
13663
+ return transport.post("/agents/ensure", body);
13664
+ }
13665
+ async function prepareAgentPromotion(input) {
13666
+ if (input.alias === "live") {
13667
+ throw new AgentPromotionError(
13668
+ "prepare stages a candidate at a preview alias and never deploys: pass a non-live alias, then promote it with activate."
13669
+ );
13670
+ }
13671
+ const pulled = await input.source.get("/agents/pull", { name: input.name });
13672
+ const converged = await ensureInto(input.target, {
13673
+ name: input.name,
13674
+ definition: pulled.definition,
13675
+ deploy: { alias: input.alias },
13676
+ ...input.version ? { version: input.version } : {}
13677
+ });
13678
+ if (converged.result === "plan") {
13679
+ throw new AgentPromotionError("The target converge answered a plan; expected a write.");
13680
+ }
13681
+ const deployment = converged.deployment;
13682
+ if (!deployment?.versionId) {
13683
+ throw new AgentPromotionError(
13684
+ `The target converge did not stage a version at "${input.alias}"; nothing to promote.`
13685
+ );
13686
+ }
13687
+ return {
13688
+ manifest: MANIFEST_VERSION,
13689
+ name: input.name,
13690
+ createdAt: (/* @__PURE__ */ new Date()).toISOString(),
13691
+ source: {
13692
+ agentId: pulled.agentId,
13693
+ versionId: pulled.versionId,
13694
+ contentHash: pulled.contentHash,
13695
+ ...input.commit ? { commit: input.commit } : {}
13696
+ },
13697
+ target: {
13698
+ agentId: converged.agentId,
13699
+ versionId: deployment.versionId,
13700
+ alias: deployment.alias,
13701
+ revision: deployment.revision,
13702
+ contentHash: converged.contentHash
13703
+ }
13704
+ };
13705
+ }
13706
+ async function validateAgentPromotion(input) {
13707
+ assertManifest(input.manifest);
13708
+ const definition = input.definition ?? await repullStagedDefinition({
13709
+ ...input.source ? { source: input.source } : {},
13710
+ manifest: input.manifest
13711
+ });
13712
+ const planned = await ensureInto(input.target, {
13713
+ name: input.manifest.name,
13714
+ definition,
13715
+ dryRun: true,
13716
+ deploy: { alias: input.manifest.target.alias }
13717
+ });
13718
+ if (planned.result !== "plan") {
13719
+ throw new AgentPromotionError(`Expected a plan from the dry run, got '${planned.result}'.`);
13720
+ }
13721
+ const staged = await findStagedReceipt(input.target, input.manifest);
13722
+ if (!staged) {
13723
+ throw new AgentPromotionError(
13724
+ `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.`
13725
+ );
13726
+ }
13727
+ const refs = readReceiptRefs(staged);
13728
+ const unresolvedRefs = refs.filter((ref) => ref.resolvedId === null).map((ref) => ref.ref);
13729
+ return { ok: unresolvedRefs.length === 0, plan: planned, unresolvedRefs, refs };
13730
+ }
13731
+ async function repullStagedDefinition(input) {
13732
+ if (!input.source) {
13733
+ throw new AgentPromotionError(
13734
+ "validate needs the definition it planned: pass definition, or pass source credentials to re-pull it."
13735
+ );
13736
+ }
13737
+ const { name } = input.manifest;
13738
+ const pulled = await input.source.get("/agents/pull", { name });
13739
+ if (pulled.contentHash !== input.manifest.source.contentHash) {
13740
+ throw new AgentPromotionError(
13741
+ `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.`
13742
+ );
13743
+ }
13744
+ return pulled.definition;
13745
+ }
13746
+ async function findStagedReceipt(target, manifest) {
13747
+ const deployments = new AgentDeploymentsNamespace(() => target);
13748
+ let cursor;
13749
+ for (let page = 0; page < MAX_RECEIPT_PAGES; page += 1) {
13750
+ const answered = await deployments.list(manifest.target.agentId, {
13751
+ alias: manifest.target.alias,
13752
+ limit: RECEIPT_PAGE_SIZE,
13753
+ ...cursor ? { cursor } : {}
13754
+ });
13755
+ const found = answered.data.find(
13756
+ (receipt) => receipt.versionId === manifest.target.versionId
13757
+ );
13758
+ if (found) return found;
13759
+ const next = answered.pagination?.nextCursor;
13760
+ if (typeof next !== "string" || next.length === 0) return null;
13761
+ cursor = next;
13762
+ }
13763
+ return null;
13764
+ }
13765
+ function readReceiptRefs(receipt) {
13766
+ const dependencies = receipt?.dependencies;
13767
+ const refs = dependencies?.refs;
13768
+ if (!Array.isArray(refs)) return [];
13769
+ return refs.flatMap((entry) => {
13770
+ if (entry === null || typeof entry !== "object") return [];
13771
+ const row = entry;
13772
+ if (typeof row.ref !== "string") return [];
13773
+ return [
13774
+ {
13775
+ ref: row.ref,
13776
+ resolvedId: typeof row.resolvedId === "string" ? row.resolvedId : null,
13777
+ fingerprint: typeof row.fingerprint === "string" ? row.fingerprint : null
13778
+ }
13779
+ ];
13780
+ });
13781
+ }
13782
+ async function activateAgentPromotion(input) {
13783
+ assertManifest(input.manifest);
13784
+ const alias = input.alias ?? "live";
13785
+ const aliases = new AgentAliasesNamespace(() => input.target);
13786
+ const current = await aliases.get(input.manifest.target.agentId, alias).catch((error) => {
13787
+ if (error instanceof AgentAliasNotFoundError) return null;
13788
+ throw error;
13789
+ });
13790
+ return aliases.activate(input.manifest.target.agentId, alias, {
13791
+ versionId: input.manifest.target.versionId,
13792
+ ...current ? { revision: current.revision } : {},
13793
+ idempotencyKey: input.idempotencyKey ?? promotionIdempotencyKey(input.manifest, alias),
13794
+ ...input.reason ? { reason: input.reason } : {},
13795
+ promotion: {
13796
+ sourceAgentId: input.manifest.source.agentId,
13797
+ ...input.manifest.source.versionId ? { sourceVersionId: input.manifest.source.versionId } : {},
13798
+ sourceContentHash: input.manifest.source.contentHash,
13799
+ ...input.manifest.source.commit ? { sourceCommit: input.manifest.source.commit } : {}
13800
+ }
13801
+ });
13802
+ }
13803
+ function promotionIdempotencyKey(manifest, alias) {
13804
+ return `promote:${manifest.target.agentId}:${alias}:${manifest.target.versionId}`;
13805
+ }
13806
+ async function promoteAgent(input) {
13807
+ const manifest = await prepareAgentPromotion(input);
13808
+ const definition = await repullStagedDefinition({ source: input.source, manifest });
13809
+ const validation = await validateAgentPromotion({ target: input.target, manifest, definition });
13810
+ if (!input.activate) return { manifest, validation };
13811
+ const activation = await activateAgentPromotion({
13812
+ target: input.target,
13813
+ manifest,
13814
+ ...input.activate
13815
+ });
13816
+ return { manifest, validation, activation };
13817
+ }
13818
+
13353
13819
  // src/transform.ts
13354
13820
  function transformQueryParams(params) {
13355
13821
  const result = {};
@@ -13367,7 +13833,7 @@ function transformQueryParams(params) {
13367
13833
 
13368
13834
  // src/version.ts
13369
13835
  var FALLBACK_VERSION = "0.0.0";
13370
- var SDK_VERSION = "9.12.0".length > 0 ? "9.12.0" : FALLBACK_VERSION;
13836
+ var SDK_VERSION = "9.13.0".length > 0 ? "9.13.0" : FALLBACK_VERSION;
13371
13837
  var RUNTYPE_CLIENT_KIND = "sdk";
13372
13838
  var SDK_USER_AGENT = `runtype-sdk/${SDK_VERSION} (typescript)`;
13373
13839
 
@@ -13746,11 +14212,11 @@ var RuntypeClient2 = class {
13746
14212
  /**
13747
14213
  * Generic PUT request
13748
14214
  */
13749
- async put(path, data) {
14215
+ async put(path, data, extraHeaders) {
13750
14216
  const url = this.buildUrl(path);
13751
14217
  const response = await this.makeRequest(url, {
13752
14218
  method: "PUT",
13753
- headers: this.headers,
14219
+ headers: { ...this.headers, ...extraHeaders },
13754
14220
  body: data ? JSON.stringify(data) : void 0
13755
14221
  });
13756
14222
  return response;
@@ -13770,11 +14236,11 @@ var RuntypeClient2 = class {
13770
14236
  /**
13771
14237
  * Generic DELETE request
13772
14238
  */
13773
- async delete(path, data) {
14239
+ async delete(path, data, extraHeaders) {
13774
14240
  const url = this.buildUrl(path);
13775
14241
  const response = await this.makeRequest(url, {
13776
14242
  method: "DELETE",
13777
- headers: this.headers,
14243
+ headers: { ...this.headers, ...extraHeaders },
13778
14244
  body: data ? JSON.stringify(data) : void 0
13779
14245
  });
13780
14246
  return response;
@@ -14635,8 +15101,16 @@ var STEP_TYPE_TO_METHOD = {
14635
15101
  "memory-summary": "memorySummary"
14636
15102
  };
14637
15103
  export {
15104
+ AgentAliasDependencyError,
15105
+ AgentAliasNotFoundError,
15106
+ AgentAliasPreviewLimitError,
15107
+ AgentAliasRevisionMismatchError,
15108
+ AgentAliasRevisionRequiredError,
15109
+ AgentAliasesNamespace,
15110
+ AgentDeploymentsNamespace,
14638
15111
  AgentDriftError,
14639
15112
  AgentEnsureConflictError,
15113
+ AgentPromotionError,
14640
15114
  AgentVersionsEndpoint,
14641
15115
  AgentsEndpoint,
14642
15116
  AgentsNamespace,
@@ -14658,6 +15132,7 @@ export {
14658
15132
  DEFAULT_RECOVERY_AFTER_EMPTY_SESSIONS,
14659
15133
  DEFAULT_STALL_STOP_AFTER,
14660
15134
  DispatchEndpoint,
15135
+ ENSURE_RELEASE_DEPLOY_CONFLICT_MESSAGE,
14661
15136
  EvalBuilder,
14662
15137
  EvalEndpoint,
14663
15138
  EvalRunner,
@@ -14675,6 +15150,7 @@ export {
14675
15150
  FlowsNamespace,
14676
15151
  IntegrationsEndpoint,
14677
15152
  LEDGER_ARTIFACT_LINE_PREFIX,
15153
+ LIVE_AGENT_ALIAS,
14678
15154
  LogsEndpoint,
14679
15155
  ModelConfigsEndpoint,
14680
15156
  ProductDriftError,
@@ -14711,6 +15187,8 @@ export {
14711
15187
  TypedRecordsScope,
14712
15188
  UNIFIED_EVENTS_QUERY,
14713
15189
  UsersEndpoint,
15190
+ activateAgentPromotion,
15191
+ agentAliasErrorCode,
14714
15192
  applyGeneratedRuntimeToolProposalToDispatchRequest,
14715
15193
  attachRuntimeToolsToDispatchRequest,
14716
15194
  buildAgentAdmissionHeaders,
@@ -14788,7 +15266,10 @@ export {
14788
15266
  parseLedgerArtifactRelativePath,
14789
15267
  parseOffloadedOutputId,
14790
15268
  parseSSEChunk,
15269
+ prepareAgentPromotion,
14791
15270
  processStream,
15271
+ promoteAgent,
15272
+ promotionIdempotencyKey,
14792
15273
  pullEval,
14793
15274
  pullFpo,
14794
15275
  ranStep,
@@ -14806,6 +15287,7 @@ export {
14806
15287
  unregisterWorkflowHook,
14807
15288
  usedNoTools,
14808
15289
  validJson,
15290
+ validateAgentPromotion,
14809
15291
  withDetachedReconnect,
14810
15292
  withUnifiedEvents
14811
15293
  };