@runtypelabs/sdk 6.3.5 → 6.4.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
@@ -300,6 +300,7 @@ function createAgentEventTranslator() {
300
300
  toolName: data.toolName,
301
301
  toolType: data.toolType,
302
302
  parameters: data.parameters,
303
+ hiddenParameterNames: data.hiddenParameterNames,
303
304
  origin: data.origin,
304
305
  pageOrigin: data.pageOrigin
305
306
  })
@@ -1628,7 +1629,11 @@ var FlowBuilder = class {
1628
1629
  const flow = this.existingFlowId ? { id: this.existingFlowId } : { name: this.flowConfig.name, steps: this.steps };
1629
1630
  const request6 = { flow };
1630
1631
  if (this.recordConfig) {
1631
- request6.record = this.recordConfig;
1632
+ const { id, ...record } = this.recordConfig;
1633
+ request6.record = {
1634
+ ...record,
1635
+ ...id !== void 0 ? { id: String(id) } : {}
1636
+ };
1632
1637
  }
1633
1638
  if (this.messagesConfig) {
1634
1639
  request6.messages = this.messagesConfig;
@@ -1771,8 +1776,7 @@ var ClientFlowBuilder = class extends FlowBuilder {
1771
1776
  let runCallbacks;
1772
1777
  let localTools;
1773
1778
  let dispatchClient = this.boundClient;
1774
- const isLocalTools = (obj) => obj && typeof obj === "object" && !isStreamCallbacks(obj) && !("streamResponse" in obj) && // Not options
1775
- !("dispatch" in obj);
1779
+ const isLocalTools = (obj) => obj && typeof obj === "object" && !Array.isArray(obj) && !isStreamCallbacks(obj) && !("dispatch" in obj) && Object.keys(obj).length > 0 && Object.values(obj).every((value) => typeof value === "function");
1776
1780
  if (arg1) {
1777
1781
  if (typeof arg1 === "object" && "dispatch" in arg1) {
1778
1782
  if (arg2) {
@@ -3493,7 +3497,7 @@ var RuntypeFlowBuilder = class {
3493
3497
  if (isStreaming) {
3494
3498
  currentResponse = await client.dispatch(config);
3495
3499
  } else {
3496
- const data = await client.post("/dispatch", config);
3500
+ const data = await client.dispatchJson(config);
3497
3501
  currentResponse = new Response(JSON.stringify(data), {
3498
3502
  headers: { "content-type": "application/json" }
3499
3503
  });
@@ -3562,7 +3566,11 @@ var RuntypeFlowBuilder = class {
3562
3566
  const flow = this.existingFlowId ? { id: this.existingFlowId } : { name: this.flowConfig.name, steps: this.steps };
3563
3567
  const request6 = { flow };
3564
3568
  if (this.recordConfig) {
3565
- request6.record = this.recordConfig;
3569
+ const { id, ...record } = this.recordConfig;
3570
+ request6.record = {
3571
+ ...record,
3572
+ ...id !== void 0 ? { id: String(id) } : {}
3573
+ };
3566
3574
  }
3567
3575
  if (this.messagesConfig) {
3568
3576
  request6.messages = this.messagesConfig;
@@ -3634,6 +3642,9 @@ var RuntypeFlowBuilder = class {
3634
3642
  if (this.mode !== "upsert" || !this.steps.length) {
3635
3643
  return client.dispatch(config);
3636
3644
  }
3645
+ if (!config.flow) {
3646
+ throw new Error("Persisted flow dispatch requires a flow target");
3647
+ }
3637
3648
  const contentHash = await this.computeContentHash();
3638
3649
  const hashOnlyConfig = {
3639
3650
  ...config,
@@ -5704,6 +5715,47 @@ function transformQueryParams(params) {
5704
5715
  return result;
5705
5716
  }
5706
5717
 
5718
+ // src/dispatch-request.ts
5719
+ function normalizeDispatchMessageContent(content) {
5720
+ if (Array.isArray(content) && content.some(
5721
+ (part) => typeof part === "object" && part !== null && "type" in part && part.type === "asset_ref"
5722
+ )) {
5723
+ throw new Error(
5724
+ "Dispatch messages cannot submit persisted asset_ref content; provide the original image or file content instead"
5725
+ );
5726
+ }
5727
+ return content;
5728
+ }
5729
+ function normalizeDispatchRequest(request6) {
5730
+ if (!request6.flow && !request6.agent) {
5731
+ throw new Error("Dispatch requires either a flow or an agent target");
5732
+ }
5733
+ const record = request6.record === void 0 ? void 0 : {
5734
+ ...request6.record,
5735
+ ...request6.record.id !== void 0 ? { id: String(request6.record.id) } : {}
5736
+ };
5737
+ const messages = request6.messages?.map((message) => ({
5738
+ ...message,
5739
+ content: normalizeDispatchMessageContent(message.content)
5740
+ }));
5741
+ const clientTools = request6.clientTools?.map((tool) => {
5742
+ if (tool.parametersSchema.type !== "object") {
5743
+ throw new Error(`Client tool "${tool.name}" parametersSchema.type must be "object"`);
5744
+ }
5745
+ return {
5746
+ ...tool,
5747
+ parametersSchema: tool.parametersSchema
5748
+ };
5749
+ });
5750
+ const normalized = {
5751
+ ...request6,
5752
+ ...record !== void 0 ? { record } : {},
5753
+ ...messages !== void 0 ? { messages } : {},
5754
+ ...clientTools !== void 0 ? { clientTools } : {}
5755
+ };
5756
+ return request6.flow ? { ...normalized, flow: request6.flow } : { ...normalized, agent: request6.agent };
5757
+ }
5758
+
5707
5759
  // src/runtype.ts
5708
5760
  var globalConfig = {};
5709
5761
  var globalClient = null;
@@ -5801,14 +5853,28 @@ var RuntypeClient = class {
5801
5853
  });
5802
5854
  }
5803
5855
  /**
5804
- * Dispatch flow execution (streaming)
5856
+ * Dispatch flow execution (streaming).
5857
+ *
5858
+ * This is the sole streaming-dispatch chokepoint for the flow builders
5859
+ * (`RuntypeFlowBuilder`), so it normalizes the request to the canonical
5860
+ * `/v1/dispatch` wire contract here — every builder path inherits the same
5861
+ * normalization the `DispatchEndpoint` applies, with no per-builder call.
5805
5862
  */
5806
5863
  async dispatch(config) {
5807
5864
  return this.requestStream("/dispatch", {
5808
5865
  method: "POST",
5809
- body: JSON.stringify(transformRequest(config))
5866
+ body: JSON.stringify(transformRequest(normalizeDispatchRequest(config)))
5810
5867
  });
5811
5868
  }
5869
+ /**
5870
+ * Dispatch flow execution (non-streaming JSON).
5871
+ *
5872
+ * The non-streaming sibling of {@link dispatch}; it normalizes to the same
5873
+ * canonical wire contract so builders never post a raw, un-normalized body.
5874
+ */
5875
+ async dispatchJson(config) {
5876
+ return this.post("/dispatch", normalizeDispatchRequest(config));
5877
+ }
5812
5878
  /**
5813
5879
  * Build full URL with query parameters
5814
5880
  */
@@ -6175,7 +6241,7 @@ var Runtype = class {
6175
6241
 
6176
6242
  // src/version.ts
6177
6243
  var FALLBACK_VERSION = "0.0.0";
6178
- var SDK_VERSION = "6.3.5".length > 0 ? "6.3.5" : FALLBACK_VERSION;
6244
+ var SDK_VERSION = "6.4.0".length > 0 ? "6.4.0" : FALLBACK_VERSION;
6179
6245
  var RUNTYPE_CLIENT_KIND = "sdk";
6180
6246
  var SDK_USER_AGENT = `runtype-sdk/${SDK_VERSION} (typescript)`;
6181
6247
 
@@ -6400,7 +6466,11 @@ function buildGeneratedRuntimeToolGateOutput(proposal, options = {}) {
6400
6466
  };
6401
6467
  }
6402
6468
  function attachRuntimeToolsToDispatchRequest(request6, runtimeTools, options = {}) {
6403
- const stepList = request6.flow.steps;
6469
+ const flow = request6.flow;
6470
+ if (!flow) {
6471
+ throw new Error("Cannot attach runtime tools: dispatch request must include flow.steps");
6472
+ }
6473
+ const stepList = flow.steps;
6404
6474
  if (!stepList || !Array.isArray(stepList) || stepList.length === 0) {
6405
6475
  throw new Error("Cannot attach runtime tools: dispatch request must include flow.steps");
6406
6476
  }
@@ -6445,7 +6515,7 @@ function attachRuntimeToolsToDispatchRequest(request6, runtimeTools, options = {
6445
6515
  return {
6446
6516
  ...request6,
6447
6517
  flow: {
6448
- ...request6.flow,
6518
+ ...flow,
6449
6519
  // `clonedSteps` is a structural clone of `request.flow.steps` (already
6450
6520
  // `FlowStepDefinition[]`); only the prompt step's `config.tools` was
6451
6521
  // merged, so every step's `type` discriminant is preserved. The clone is
@@ -8720,7 +8790,7 @@ var DispatchEndpoint = class {
8720
8790
  * Dispatch: create and/or execute flows on records atomically
8721
8791
  */
8722
8792
  async execute(data) {
8723
- return this.client.post("/dispatch", data);
8793
+ return this.client.post("/dispatch", normalizeDispatchRequest(data));
8724
8794
  }
8725
8795
  /**
8726
8796
  * Dispatch with streaming response
@@ -8728,7 +8798,7 @@ var DispatchEndpoint = class {
8728
8798
  async executeStream(data) {
8729
8799
  return this.client.requestStream("/dispatch", {
8730
8800
  method: "POST",
8731
- body: JSON.stringify(data)
8801
+ body: JSON.stringify(normalizeDispatchRequest(data))
8732
8802
  });
8733
8803
  }
8734
8804
  /**
@@ -11461,7 +11531,7 @@ var _AgentsEndpoint = class _AgentsEndpoint {
11461
11531
  const references = /* @__PURE__ */ new Set();
11462
11532
  const offloadPrefix = "[Output saved to ";
11463
11533
  const ledgerArtifactPrefix = LEDGER_ARTIFACT_LINE_PREFIX;
11464
- const savedToPattern = /saved to\s+([^—\]\n\s][^—\]\n]*?)(?:\s+—|\]|\n|$)/gi;
11534
+ const savedToPattern = /saved to\s+([^—\]\n\s][^—\]\n]*?)(?:—|\]|\n|$)/gi;
11465
11535
  for (const message of messages) {
11466
11536
  if (!message.toolResults) continue;
11467
11537
  for (const toolResult of message.toolResults) {
@@ -12613,6 +12683,21 @@ function hasToolEntryShape(value) {
12613
12683
  if (!isObjectRecord(value)) return false;
12614
12684
  return typeof value.execute === "function" && typeof value.description === "string" && typeof value.parametersSchema === "object" && value.parametersSchema !== null;
12615
12685
  }
12686
+ function assertTurnScopedLocalTools(localTools) {
12687
+ for (const [name, entry] of Object.entries(localTools)) {
12688
+ if (typeof entry === "function") continue;
12689
+ if (!hasToolEntryShape(entry)) {
12690
+ throw new Error(
12691
+ `Turn-scoped local tool "${name}" must be a function or an entry with description, parametersSchema, and execute`
12692
+ );
12693
+ }
12694
+ if (entry.parametersSchema.type !== "object") {
12695
+ throw new Error(
12696
+ `Turn-scoped local tool "${name}" parametersSchema.type must be "object"`
12697
+ );
12698
+ }
12699
+ }
12700
+ }
12616
12701
  function isPausedLocalActionResult(value) {
12617
12702
  return isObjectRecord(value) && value.status === "paused" && Array.isArray(value.pausedTools) && value.pausedTools.length > 0;
12618
12703
  }
@@ -12708,6 +12793,9 @@ var RuntypeClient2 = class {
12708
12793
  const options = (isOptionsObject(arg3) ? arg3 : arg4) ?? {};
12709
12794
  const scope = options.scope ?? "session";
12710
12795
  const isStreaming = !!callbacks;
12796
+ if (scope === "turn") {
12797
+ assertTurnScopedLocalTools(localTools);
12798
+ }
12711
12799
  const derivedClientTools = scope === "turn" ? Object.entries(localTools).filter((entry) => hasToolEntryShape(entry[1])).map(([name, entry]) => ({
12712
12800
  name,
12713
12801
  description: entry.description,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@runtypelabs/sdk",
3
- "version": "6.3.5",
3
+ "version": "6.4.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",