@dbx-tools/shared-model 0.3.26 → 0.3.27

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/package.json CHANGED
@@ -12,14 +12,14 @@
12
12
  },
13
13
  "dependencies": {
14
14
  "zod": "^4.3.6",
15
- "@dbx-tools/shared-core": "0.3.26"
15
+ "@dbx-tools/shared-core": "0.3.27"
16
16
  },
17
17
  "main": "index.ts",
18
18
  "license": "UNLICENSED",
19
19
  "publishConfig": {
20
20
  "access": "public"
21
21
  },
22
- "version": "0.3.26",
22
+ "version": "0.3.27",
23
23
  "types": "index.ts",
24
24
  "type": "module",
25
25
  "exports": {
@@ -29,6 +29,8 @@
29
29
  * - {@link sanitizeResponsesTools} keeps only `function` tools on a Responses
30
30
  * request body (for `/open-responses` / Anthropic, which reject Codex
31
31
  * built-ins like `web_search`).
32
+ * - {@link sanitizeOpenResponsesInput} rewrites `output_*` content part types
33
+ * in `input` to `input_*` (Open Responses rejects `output_text` in history).
32
34
  *
33
35
  * Only the surface real clients exercise is translated; unknown fields are
34
36
  * ignored rather than rejected, so a newer client degrades instead of breaking.
@@ -643,3 +645,52 @@ export function sanitizeResponsesTools(
643
645
  }
644
646
  return next;
645
647
  }
648
+
649
+ /**
650
+ * Rewrite Responses `input` content parts so Open Responses will accept them.
651
+ *
652
+ * OpenAI `/responses` (and Codex) replay prior assistant turns with
653
+ * `output_text` / `output_*` content part types. Databricks Open Responses
654
+ * (Claude, Gemini, …) only allows input-side types:
655
+ * "Open Responses input content part type 'output_text' is not supported.
656
+ * Supported: input_text, input_image, input_file, input_audio."
657
+ * Map every `output_<kind>` part to `input_<kind>` (shallow copy; no mutation).
658
+ * Call together with {@link sanitizeResponsesTools} before forwarding to
659
+ * `/serving-endpoints/open-responses`.
660
+ */
661
+ export function sanitizeOpenResponsesInput(
662
+ body: Record<string, unknown>,
663
+ ): Record<string, unknown> {
664
+ if (!Array.isArray(body.input) || body.input.length === 0) return body;
665
+
666
+ let changed = false;
667
+ const input = body.input.map((raw) => {
668
+ if (!raw || typeof raw !== "object") return raw;
669
+ const item = raw as Record<string, unknown>;
670
+ if (!Array.isArray(item.content)) return raw;
671
+
672
+ let partChanged = false;
673
+ const content = item.content.map((part) => {
674
+ if (!part || typeof part !== "object") return part;
675
+ const p = part as Record<string, unknown>;
676
+ if (typeof p.type !== "string" || !p.type.startsWith("output_")) return part;
677
+ partChanged = true;
678
+ return { ...p, type: `input_${p.type.slice("output_".length)}` };
679
+ });
680
+ if (!partChanged) return raw;
681
+ changed = true;
682
+ return { ...item, content };
683
+ });
684
+
685
+ return changed ? { ...body, input } : body;
686
+ }
687
+
688
+ /**
689
+ * Full Open Responses request sanitizer: strip non-`function` tools and rewrite
690
+ * `output_*` input content parts. Safe no-op when nothing needs changing.
691
+ */
692
+ export function sanitizeOpenResponsesRequest(
693
+ body: Record<string, unknown>,
694
+ ): Record<string, unknown> {
695
+ return sanitizeOpenResponsesInput(sanitizeResponsesTools(body));
696
+ }