@runtypelabs/sdk 4.14.0 → 4.15.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
@@ -1094,20 +1094,20 @@ var FlowBuilder = class {
1094
1094
  */
1095
1095
  build() {
1096
1096
  const flow = this.existingFlowId ? { id: this.existingFlowId } : { name: this.flowConfig.name, steps: this.steps };
1097
- const request3 = { flow };
1097
+ const request4 = { flow };
1098
1098
  if (this.recordConfig) {
1099
- request3.record = this.recordConfig;
1099
+ request4.record = this.recordConfig;
1100
1100
  }
1101
1101
  if (this.messagesConfig) {
1102
- request3.messages = this.messagesConfig;
1102
+ request4.messages = this.messagesConfig;
1103
1103
  }
1104
1104
  if (this.inputsConfig) {
1105
- request3.inputs = this.inputsConfig;
1105
+ request4.inputs = this.inputsConfig;
1106
1106
  }
1107
1107
  if (Object.keys(this.optionsConfig).length > 0) {
1108
- request3.options = this.optionsConfig;
1108
+ request4.options = this.optionsConfig;
1109
1109
  }
1110
- return request3;
1110
+ return request4;
1111
1111
  }
1112
1112
  /**
1113
1113
  * Validate this prospective flow against the public validation endpoint
@@ -2501,15 +2501,15 @@ var RuntypeFlowBuilder = class {
2501
2501
  build() {
2502
2502
  const flowMode = this.mode === "existing" ? "existing" : this.mode;
2503
2503
  const flow = this.existingFlowId ? { id: this.existingFlowId } : { name: this.flowConfig.name, steps: this.steps };
2504
- const request3 = { flow };
2504
+ const request4 = { flow };
2505
2505
  if (this.recordConfig) {
2506
- request3.record = this.recordConfig;
2506
+ request4.record = this.recordConfig;
2507
2507
  }
2508
2508
  if (this.messagesConfig) {
2509
- request3.messages = this.messagesConfig;
2509
+ request4.messages = this.messagesConfig;
2510
2510
  }
2511
2511
  if (this.inputsConfig) {
2512
- request3.inputs = this.inputsConfig;
2512
+ request4.inputs = this.inputsConfig;
2513
2513
  }
2514
2514
  const options = {
2515
2515
  flowMode,
@@ -2527,8 +2527,8 @@ var RuntypeFlowBuilder = class {
2527
2527
  if (this.mode === "upsert" && Object.keys(this.upsertOptions).length > 0) {
2528
2528
  options.upsertOptions = this.upsertOptions;
2529
2529
  }
2530
- request3.options = options;
2531
- return request3;
2530
+ request4.options = options;
2531
+ return request4;
2532
2532
  }
2533
2533
  /**
2534
2534
  * Validate this prospective flow against the public validation endpoint
@@ -3809,6 +3809,219 @@ var ToolsNamespace = class {
3809
3809
  }
3810
3810
  };
3811
3811
 
3812
+ // src/products-ensure.ts
3813
+ function isPlainObject4(value) {
3814
+ return value !== null && typeof value === "object" && !Array.isArray(value);
3815
+ }
3816
+ function normalizeValue3(value) {
3817
+ if (Array.isArray(value)) {
3818
+ return value.map((item) => normalizeValue3(item));
3819
+ }
3820
+ if (isPlainObject4(value)) {
3821
+ const normalized = {};
3822
+ for (const key of Object.keys(value).sort()) {
3823
+ const entry = value[key];
3824
+ if (entry === void 0 || entry === null) continue;
3825
+ normalized[key] = normalizeValue3(entry);
3826
+ }
3827
+ return normalized;
3828
+ }
3829
+ return value;
3830
+ }
3831
+ function normalizeProductDefinition(definition) {
3832
+ const spec = isPlainObject4(definition.spec) ? normalizeValue3(definition.spec) : {};
3833
+ return {
3834
+ ...definition.description ? { description: definition.description } : {},
3835
+ ...definition.icon ? { icon: definition.icon } : {},
3836
+ spec
3837
+ };
3838
+ }
3839
+ async function computeProductContentHash(definition) {
3840
+ const serialized = JSON.stringify(normalizeProductDefinition(definition));
3841
+ const encoded = new TextEncoder().encode(serialized);
3842
+ const hashBuffer = await crypto.subtle.digest("SHA-256", encoded);
3843
+ return Array.from(new Uint8Array(hashBuffer)).map((b) => b.toString(16).padStart(2, "0")).join("");
3844
+ }
3845
+ var DEFINE_PRODUCT_TOP_LEVEL_KEYS = /* @__PURE__ */ new Set(["name", "description", "icon", "spec"]);
3846
+ function defineProduct(input) {
3847
+ if (!input || typeof input !== "object") {
3848
+ throw new Error("defineProduct requires a definition object");
3849
+ }
3850
+ if (typeof input.name !== "string" || input.name.length === 0) {
3851
+ throw new Error('defineProduct requires a non-empty string "name"');
3852
+ }
3853
+ if (input.description != null && typeof input.description !== "string") {
3854
+ throw new Error('defineProduct "description" must be a string when provided');
3855
+ }
3856
+ if (input.icon != null && typeof input.icon !== "string") {
3857
+ throw new Error('defineProduct "icon" must be a string when provided');
3858
+ }
3859
+ if (input.spec != null && !isPlainObject4(input.spec)) {
3860
+ throw new Error('defineProduct "spec" must be an object when provided');
3861
+ }
3862
+ const unknownKeys = Object.keys(input).filter((key) => !DEFINE_PRODUCT_TOP_LEVEL_KEYS.has(key));
3863
+ if (unknownKeys.length > 0) {
3864
+ throw new Error(
3865
+ `defineProduct: unknown field(s): ${unknownKeys.join(", ")}. Allowed fields are name, description, icon, spec. (canvas / nested capabilities and surfaces are not converged by ensure.)`
3866
+ );
3867
+ }
3868
+ return {
3869
+ name: input.name,
3870
+ ...input.description !== void 0 ? { description: input.description } : {},
3871
+ ...input.icon !== void 0 ? { icon: input.icon } : {},
3872
+ ...input.spec !== void 0 ? { spec: input.spec } : {}
3873
+ };
3874
+ }
3875
+ var ProductEnsureConflictError = class extends Error {
3876
+ constructor(body) {
3877
+ super(body.error ?? `Product ensure conflict: ${body.code}`);
3878
+ this.name = "ProductEnsureConflictError";
3879
+ this.code = body.code;
3880
+ this.lastModifiedSource = body.lastModifiedSource;
3881
+ this.modifiedAt = body.modifiedAt;
3882
+ this.currentHash = body.currentHash;
3883
+ }
3884
+ };
3885
+ var ProductDriftError = class extends Error {
3886
+ constructor(plan) {
3887
+ super(
3888
+ `Product "${plan.productId ?? "definition"}" drifted: plan is '${plan.changes}' (changed: ${plan.changedKeys.join(", ") || "n/a"}). Run client.products.pull(name) to absorb the remote edit into your repo, or re-run ensure to converge.`
3889
+ );
3890
+ this.name = "ProductDriftError";
3891
+ this.plan = plan;
3892
+ }
3893
+ };
3894
+ function parseRequestError4(err) {
3895
+ if (!(err instanceof Error)) return { status: null, body: null };
3896
+ const match = err.message.match(/^API request failed: (\d{3}) .*? - ([\s\S]*)$/);
3897
+ if (!match) return { status: null, body: null };
3898
+ try {
3899
+ return { status: Number(match[1]), body: JSON.parse(match[2]) };
3900
+ } catch {
3901
+ return { status: Number(match[1]), body: null };
3902
+ }
3903
+ }
3904
+ function toConflictError4(err) {
3905
+ const { status, body } = parseRequestError4(err);
3906
+ if (status !== 409 || !isPlainObject4(body)) return null;
3907
+ const code = body.code;
3908
+ if (code !== "external_modification" && code !== "remote_changed") return null;
3909
+ return new ProductEnsureConflictError(
3910
+ body
3911
+ );
3912
+ }
3913
+ var serverHashMemo4 = /* @__PURE__ */ new WeakMap();
3914
+ function memoFor4(client) {
3915
+ let memo = serverHashMemo4.get(client);
3916
+ if (!memo) {
3917
+ memo = /* @__PURE__ */ new Map();
3918
+ serverHashMemo4.set(client, memo);
3919
+ }
3920
+ return memo;
3921
+ }
3922
+ function memoize3(memo, memoKey, result) {
3923
+ if (result.result !== "plan") memo.set(memoKey, result.contentHash);
3924
+ }
3925
+ async function request3(client, body) {
3926
+ try {
3927
+ return await client.post(
3928
+ "/products/ensure",
3929
+ body
3930
+ );
3931
+ } catch (err) {
3932
+ const conflict = toConflictError4(err);
3933
+ if (conflict) throw conflict;
3934
+ throw err;
3935
+ }
3936
+ }
3937
+ async function ensureProduct(client, definition, options = {}) {
3938
+ const { dryRun, onConflict, expectedRemoteHash, expectNoChanges } = options;
3939
+ const passthrough = {
3940
+ ...onConflict ? { onConflict } : {},
3941
+ ...expectedRemoteHash ? { expectedRemoteHash } : {}
3942
+ };
3943
+ if (dryRun || expectNoChanges) {
3944
+ const plan = await request3(client, {
3945
+ name: definition.name,
3946
+ definition,
3947
+ dryRun: true,
3948
+ ...passthrough
3949
+ });
3950
+ if (plan.result !== "plan") {
3951
+ throw new Error(`Expected a plan result from dryRun, got '${plan.result}'`);
3952
+ }
3953
+ if (expectNoChanges && plan.changes !== "none") {
3954
+ throw new ProductDriftError(plan);
3955
+ }
3956
+ return plan;
3957
+ }
3958
+ const memo = memoFor4(client);
3959
+ const localHash = await computeProductContentHash(definition);
3960
+ const memoKey = `${definition.name} ${localHash}`;
3961
+ const contentHash = memo.get(memoKey) ?? localHash;
3962
+ const probe = await request3(client, {
3963
+ name: definition.name,
3964
+ contentHash,
3965
+ ...passthrough
3966
+ });
3967
+ if (probe.result !== "definitionRequired") {
3968
+ memoize3(memo, memoKey, probe);
3969
+ return probe;
3970
+ }
3971
+ const converged = await request3(client, {
3972
+ name: definition.name,
3973
+ definition,
3974
+ ...passthrough
3975
+ });
3976
+ if (converged.result === "definitionRequired") {
3977
+ throw new Error("Server reported definitionRequired for a full-definition request");
3978
+ }
3979
+ memoize3(memo, memoKey, converged);
3980
+ return converged;
3981
+ }
3982
+ async function pullProduct(client, name) {
3983
+ return client.get("/products/pull", { name });
3984
+ }
3985
+
3986
+ // src/products-namespace.ts
3987
+ var ProductsNamespace = class {
3988
+ constructor(getClient) {
3989
+ this.getClient = getClient;
3990
+ }
3991
+ /**
3992
+ * Idempotently converge a `defineProduct` definition onto the platform.
3993
+ * Hash-first: the steady state is one tiny probe request. Creates or updates
3994
+ * the top-level product record; never deletes. Identity is name + account
3995
+ * scope.
3996
+ *
3997
+ * @example
3998
+ * ```typescript
3999
+ * const product = defineProduct({
4000
+ * name: 'Support Copilot',
4001
+ * description: 'An AI support assistant',
4002
+ * icon: '🤖',
4003
+ * spec: { productGoal: 'Deflect tier-1 tickets', productStage: 'beta' },
4004
+ * })
4005
+ *
4006
+ * // Converge (CI/deploy).
4007
+ * const result = await Runtype.products.ensure(product)
4008
+ *
4009
+ * // PR drift gate.
4010
+ * await Runtype.products.ensure(product, { expectNoChanges: true })
4011
+ * ```
4012
+ */
4013
+ async ensure(definition, options = {}) {
4014
+ return ensureProduct(this.getClient(), definition, options);
4015
+ }
4016
+ /**
4017
+ * Pull the canonical definition + provenance for a product by name — the
4018
+ * absorb-drift direction of the ensure protocol.
4019
+ */
4020
+ async pull(name) {
4021
+ return pullProduct(this.getClient(), name);
4022
+ }
4023
+ };
4024
+
3812
4025
  // src/transform.ts
3813
4026
  function transformResponse(data) {
3814
4027
  return data;
@@ -4225,6 +4438,37 @@ var Runtype = class {
4225
4438
  static get tools() {
4226
4439
  return new ToolsNamespace(() => this.getClient());
4227
4440
  }
4441
+ /**
4442
+ * Products namespace - Product config-as-code (define / ensure / pull)
4443
+ *
4444
+ * Converges the top-level product record (description, icon, spec). Nested
4445
+ * capabilities/surfaces/tools and the canvas UI layout state are not
4446
+ * converged by ensure.
4447
+ *
4448
+ * @example
4449
+ * ```typescript
4450
+ * import { defineProduct, Runtype } from '@runtypelabs/sdk'
4451
+ *
4452
+ * const product = defineProduct({
4453
+ * name: 'Support Copilot',
4454
+ * description: 'An AI support assistant',
4455
+ * icon: '🤖',
4456
+ * spec: { productGoal: 'Deflect tier-1 tickets', productStage: 'beta' },
4457
+ * })
4458
+ *
4459
+ * // Converge at deploy time (idempotent; one tiny probe in steady state)
4460
+ * await Runtype.products.ensure(product)
4461
+ *
4462
+ * // CI drift gate
4463
+ * await Runtype.products.ensure(product, { expectNoChanges: true })
4464
+ *
4465
+ * // Absorb a dashboard edit back into the repo
4466
+ * const { definition } = await Runtype.products.pull('Support Copilot')
4467
+ * ```
4468
+ */
4469
+ static get products() {
4470
+ return new ProductsNamespace(() => this.getClient());
4471
+ }
4228
4472
  };
4229
4473
 
4230
4474
  // src/generated-tool-gate.ts
@@ -4447,8 +4691,8 @@ function buildGeneratedRuntimeToolGateOutput(proposal, options = {}) {
4447
4691
  ...decision.tool ? { tool: decision.tool } : {}
4448
4692
  };
4449
4693
  }
4450
- function attachRuntimeToolsToDispatchRequest(request3, runtimeTools, options = {}) {
4451
- const stepList = request3.flow.steps;
4694
+ function attachRuntimeToolsToDispatchRequest(request4, runtimeTools, options = {}) {
4695
+ const stepList = request4.flow.steps;
4452
4696
  if (!stepList || !Array.isArray(stepList) || stepList.length === 0) {
4453
4697
  throw new Error("Cannot attach runtime tools: dispatch request must include flow.steps");
4454
4698
  }
@@ -4491,9 +4735,9 @@ function attachRuntimeToolsToDispatchRequest(request3, runtimeTools, options = {
4491
4735
  }
4492
4736
  };
4493
4737
  return {
4494
- ...request3,
4738
+ ...request4,
4495
4739
  flow: {
4496
- ...request3.flow,
4740
+ ...request4.flow,
4497
4741
  // `clonedSteps` is a structural clone of `request.flow.steps` (already
4498
4742
  // `FlowStepDefinition[]`); only the prompt step's `config.tools` was
4499
4743
  // merged, so every step's `type` discriminant is preserved. The clone is
@@ -4503,12 +4747,12 @@ function attachRuntimeToolsToDispatchRequest(request3, runtimeTools, options = {
4503
4747
  }
4504
4748
  };
4505
4749
  }
4506
- function applyGeneratedRuntimeToolProposalToDispatchRequest(request3, proposal, options = {}) {
4750
+ function applyGeneratedRuntimeToolProposalToDispatchRequest(request4, proposal, options = {}) {
4507
4751
  const decision = evaluateGeneratedRuntimeToolProposal(proposal, options.gate);
4508
4752
  if (!decision.approved || !decision.tool) {
4509
- return { decision, request: request3 };
4753
+ return { decision, request: request4 };
4510
4754
  }
4511
- const nextRequest = attachRuntimeToolsToDispatchRequest(request3, [decision.tool], options.attach);
4755
+ const nextRequest = attachRuntimeToolsToDispatchRequest(request4, [decision.tool], options.attach);
4512
4756
  return {
4513
4757
  decision,
4514
4758
  request: nextRequest
@@ -6758,15 +7002,15 @@ var DispatchEndpoint = class {
6758
7002
  * Attach approved runtime tools to a prompt step in a redispatch request.
6759
7003
  * Returns a new request object and does not mutate the original.
6760
7004
  */
6761
- attachApprovedRuntimeTools(request3, runtimeTools, options) {
6762
- return attachRuntimeToolsToDispatchRequest(request3, runtimeTools, options);
7005
+ attachApprovedRuntimeTools(request4, runtimeTools, options) {
7006
+ return attachRuntimeToolsToDispatchRequest(request4, runtimeTools, options);
6763
7007
  }
6764
7008
  /**
6765
7009
  * Validate a generated runtime tool proposal and attach it to the redispatch
6766
7010
  * request if approved, in one call.
6767
7011
  */
6768
- applyGeneratedRuntimeToolProposal(request3, proposal, options) {
6769
- return applyGeneratedRuntimeToolProposalToDispatchRequest(request3, proposal, options);
7012
+ applyGeneratedRuntimeToolProposal(request4, proposal, options) {
7013
+ return applyGeneratedRuntimeToolProposalToDispatchRequest(request4, proposal, options);
6770
7014
  }
6771
7015
  };
6772
7016
  var ChatEndpoint = class {
@@ -7318,8 +7562,8 @@ var GENERATED_RUNTIME_TOOL_PROPOSAL_SCHEMA = {
7318
7562
  },
7319
7563
  required: ["name", "description", "toolType", "parametersSchema", "config"]
7320
7564
  };
7321
- function appendRuntimeToolsToAgentRequest(request3, runtimeTools) {
7322
- const existing = request3.tools?.runtimeTools || [];
7565
+ function appendRuntimeToolsToAgentRequest(request4, runtimeTools) {
7566
+ const existing = request4.tools?.runtimeTools || [];
7323
7567
  const existingNames = new Set(existing.map((tool) => tool.name));
7324
7568
  const converted = runtimeTools.filter((tool) => !existingNames.has(tool.name)).map((tool) => ({
7325
7569
  name: tool.name,
@@ -7329,9 +7573,9 @@ function appendRuntimeToolsToAgentRequest(request3, runtimeTools) {
7329
7573
  ...tool.config ? { config: tool.config } : {}
7330
7574
  }));
7331
7575
  return {
7332
- ...request3,
7576
+ ...request4,
7333
7577
  tools: {
7334
- ...request3.tools,
7578
+ ...request4.tools,
7335
7579
  runtimeTools: [...existing, ...converted]
7336
7580
  }
7337
7581
  };
@@ -7407,21 +7651,21 @@ var _AgentsEndpoint = class _AgentsEndpoint {
7407
7651
  * Attach approved runtime tools to an agent execute request.
7408
7652
  * Returns a new request object and does not mutate the original.
7409
7653
  */
7410
- attachApprovedRuntimeTools(request3, runtimeTools) {
7411
- return appendRuntimeToolsToAgentRequest(request3, runtimeTools);
7654
+ attachApprovedRuntimeTools(request4, runtimeTools) {
7655
+ return appendRuntimeToolsToAgentRequest(request4, runtimeTools);
7412
7656
  }
7413
7657
  /**
7414
7658
  * Validate a generated runtime tool proposal and append it to an agent execute
7415
7659
  * request if approved, in one call.
7416
7660
  */
7417
- applyGeneratedRuntimeToolProposal(request3, proposal, options) {
7661
+ applyGeneratedRuntimeToolProposal(request4, proposal, options) {
7418
7662
  const decision = evaluateGeneratedRuntimeToolProposal(proposal, options);
7419
7663
  if (!decision.approved || !decision.tool) {
7420
- return { decision, request: request3 };
7664
+ return { decision, request: request4 };
7421
7665
  }
7422
7666
  return {
7423
7667
  decision,
7424
- request: appendRuntimeToolsToAgentRequest(request3, [decision.tool])
7668
+ request: appendRuntimeToolsToAgentRequest(request4, [decision.tool])
7425
7669
  };
7426
7670
  }
7427
7671
  /**
@@ -10657,7 +10901,7 @@ var RuntypeClient2 = class {
10657
10901
  clearApiKey() {
10658
10902
  delete this.headers.Authorization;
10659
10903
  }
10660
- async runWithLocalTools(request3, localTools, arg3, arg4) {
10904
+ async runWithLocalTools(request4, localTools, arg3, arg4) {
10661
10905
  const isOptionsObject = (val) => typeof val === "object" && val !== null && "scope" in val;
10662
10906
  const callbacks = isOptionsObject(arg3) ? void 0 : arg3;
10663
10907
  const options = (isOptionsObject(arg3) ? arg3 : arg4) ?? {};
@@ -10671,12 +10915,12 @@ var RuntypeClient2 = class {
10671
10915
  ...entry.pageOrigin ? { pageOrigin: entry.pageOrigin } : {}
10672
10916
  })) : [];
10673
10917
  const modifiedRequest = {
10674
- ...request3,
10918
+ ...request4,
10675
10919
  ...derivedClientTools.length > 0 ? {
10676
- clientTools: [...request3.clientTools ?? [], ...derivedClientTools]
10920
+ clientTools: [...request4.clientTools ?? [], ...derivedClientTools]
10677
10921
  } : {},
10678
10922
  options: {
10679
- ...request3.options || {},
10923
+ ...request4.options || {},
10680
10924
  streamResponse: isStreaming
10681
10925
  }
10682
10926
  };
@@ -11114,20 +11358,20 @@ var BatchBuilder = class {
11114
11358
  if (!this.recordType) {
11115
11359
  throw new Error("BatchBuilder: recordType is required. Call .forRecordType(type) first.");
11116
11360
  }
11117
- const request3 = {
11361
+ const request4 = {
11118
11362
  flowId: this.flowId,
11119
11363
  recordType: this.recordType
11120
11364
  };
11121
11365
  if (Object.keys(this.batchOptions).length > 0) {
11122
- request3.options = this.batchOptions;
11366
+ request4.options = this.batchOptions;
11123
11367
  }
11124
11368
  if (this.filterConfig) {
11125
- request3.filter = this.filterConfig;
11369
+ request4.filter = this.filterConfig;
11126
11370
  }
11127
11371
  if (this.limitConfig !== void 0) {
11128
- request3.limit = this.limitConfig;
11372
+ request4.limit = this.limitConfig;
11129
11373
  }
11130
- return request3;
11374
+ return request4;
11131
11375
  }
11132
11376
  /**
11133
11377
  * Execute the batch operation
@@ -11284,32 +11528,32 @@ var EvalBuilder = class {
11284
11528
  "EvalBuilder: records are required. Call .forRecordType(type) or .withRecords([...]) first."
11285
11529
  );
11286
11530
  }
11287
- const request3 = {};
11531
+ const request4 = {};
11288
11532
  if (this.flowId) {
11289
- request3.flowId = this.flowId;
11533
+ request4.flowId = this.flowId;
11290
11534
  } else if (this.virtualFlow) {
11291
- request3.flow = this.virtualFlow;
11535
+ request4.flow = this.virtualFlow;
11292
11536
  }
11293
11537
  if (this.recordType) {
11294
- request3.recordType = this.recordType;
11538
+ request4.recordType = this.recordType;
11295
11539
  } else if (this.inlineRecords) {
11296
- request3.records = this.inlineRecords;
11540
+ request4.records = this.inlineRecords;
11297
11541
  }
11298
11542
  if (this.modelOverrides) {
11299
- request3.modelOverrides = this.modelOverrides;
11543
+ request4.modelOverrides = this.modelOverrides;
11300
11544
  } else if (this.modelConfigs) {
11301
- request3.modelConfigs = this.modelConfigs;
11545
+ request4.modelConfigs = this.modelConfigs;
11302
11546
  }
11303
11547
  if (Object.keys(this.evalOptions).length > 0) {
11304
- request3.options = this.evalOptions;
11548
+ request4.options = this.evalOptions;
11305
11549
  }
11306
11550
  if (this.filterConfig) {
11307
- request3.filter = this.filterConfig;
11551
+ request4.filter = this.filterConfig;
11308
11552
  }
11309
11553
  if (this.limitConfig !== void 0) {
11310
- request3.limit = this.limitConfig;
11554
+ request4.limit = this.limitConfig;
11311
11555
  }
11312
- return request3;
11556
+ return request4;
11313
11557
  }
11314
11558
  /**
11315
11559
  * Execute the evaluation
@@ -11812,6 +12056,9 @@ export {
11812
12056
  LEDGER_ARTIFACT_LINE_PREFIX,
11813
12057
  LogsEndpoint,
11814
12058
  ModelConfigsEndpoint,
12059
+ ProductDriftError,
12060
+ ProductEnsureConflictError,
12061
+ ProductsNamespace,
11815
12062
  PromptRunner,
11816
12063
  PromptsEndpoint,
11817
12064
  PromptsNamespace,
@@ -11843,6 +12090,7 @@ export {
11843
12090
  compileWorkflowConfig,
11844
12091
  computeAgentContentHash,
11845
12092
  computeFlowContentHash,
12093
+ computeProductContentHash,
11846
12094
  computeToolContentHash,
11847
12095
  createClient,
11848
12096
  createExternalTool,
@@ -11851,6 +12099,7 @@ export {
11851
12099
  defineAgent,
11852
12100
  defineFlow,
11853
12101
  definePlaybook,
12102
+ defineProduct,
11854
12103
  defineTool,
11855
12104
  deployWorkflow,
11856
12105
  ensureDefaultWorkflowHooks,
@@ -11867,6 +12116,7 @@ export {
11867
12116
  listWorkflowHooks,
11868
12117
  normalizeAgentDefinition,
11869
12118
  normalizeCandidatePath,
12119
+ normalizeProductDefinition,
11870
12120
  normalizeToolDefinition,
11871
12121
  parseFinalBuffer,
11872
12122
  parseLedgerArtifactRelativePath,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@runtypelabs/sdk",
3
- "version": "4.14.0",
3
+ "version": "4.15.0",
4
4
  "type": "module",
5
5
  "description": "TypeScript SDK for the Runtype API with fluent methods. Use it to quickly realize AI products, agents, and workflows.",
6
6
  "main": "dist/index.cjs",