@dbx-tools/cli-model-proxy 0.3.26 → 0.3.28

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.
Files changed (3) hide show
  1. package/README.md +5 -2
  2. package/package.json +4 -4
  3. package/src/server.ts +18 -10
package/README.md CHANGED
@@ -134,8 +134,11 @@ Use this when tests or local developer tools need a managed proxy lifecycle.
134
134
  Responses-only models (Codex) which are translated and posted to
135
135
  `/serving-endpoints/responses`.
136
136
  - Responses → `/serving-endpoints/responses` (OpenAI-family) or
137
- `/serving-endpoints/open-responses` (Claude/Gemini/…), body forwarded
138
- as-is.
137
+ `/serving-endpoints/open-responses` (Claude/Gemini/…). For Open
138
+ Responses the proxy strips non-`function` tools, rewrites prior-turn
139
+ `output_*` content parts to `input_*`, and drops Claude
140
+ `thinking` / `redacted_thinking` / `reasoning` blocks (replay of those
141
+ signed blobs fails with "Invalid `data` in `redacted_thinking`").
139
142
  5. JSON or SSE response bodies are piped back (with a chat↔Responses
140
143
  translation only when a chat client hit a Responses-only model).
141
144
 
package/package.json CHANGED
@@ -18,16 +18,16 @@
18
18
  "@databricks/sdk-experimental": "^0.17.0",
19
19
  "commander": "^15.0.0",
20
20
  "tsx": "^4.23.0",
21
- "@dbx-tools/model": "0.3.26",
22
- "@dbx-tools/shared-core": "0.3.26",
23
- "@dbx-tools/shared-model": "0.3.26"
21
+ "@dbx-tools/model": "0.3.28",
22
+ "@dbx-tools/shared-core": "0.3.28",
23
+ "@dbx-tools/shared-model": "0.3.28"
24
24
  },
25
25
  "main": "index.ts",
26
26
  "license": "UNLICENSED",
27
27
  "publishConfig": {
28
28
  "access": "public"
29
29
  },
30
- "version": "0.3.26",
30
+ "version": "0.3.28",
31
31
  "types": "index.ts",
32
32
  "type": "module",
33
33
  "exports": {
package/src/server.ts CHANGED
@@ -38,7 +38,7 @@ import { classify, openaiChat, openaiResponses } from "@dbx-tools/shared-model";
38
38
  import type { DatabricksBackend } from "./backend";
39
39
  import { DEFAULT_BIND_HOST, DEFAULT_PORT } from "./defaults";
40
40
 
41
- const { chatToResponsesRequest, responseToChatCompletion, sanitizeResponsesTools } =
41
+ const { chatToResponsesRequest, responseToChatCompletion, sanitizeOpenResponsesRequest } =
42
42
  openaiResponses;
43
43
 
44
44
  const logger = log.logger("model-proxy/server");
@@ -301,18 +301,23 @@ async function proxyChatViaResponses(
301
301
  headers["content-type"] = "application/json";
302
302
  headers.accept = "application/json";
303
303
 
304
+ const upstreamUrl = backend.responsesUrl(modelId);
305
+ const forward = upstreamUrl.includes("/open-responses")
306
+ ? sanitizeOpenResponsesRequest(responses)
307
+ : responses;
308
+
304
309
  logger.info("proxy", {
305
310
  requested,
306
311
  resolved: modelId,
307
312
  matched,
308
- upstream: "responses",
313
+ upstream: upstreamUrl,
309
314
  stream: false,
310
315
  });
311
316
 
312
- const upstream = await fetch(backend.responsesUrl(modelId), {
317
+ const upstream = await fetch(upstreamUrl, {
313
318
  method: "POST",
314
319
  headers,
315
- body: JSON.stringify(responses),
320
+ body: JSON.stringify(forward),
316
321
  });
317
322
 
318
323
  if (!upstream.ok) {
@@ -331,9 +336,12 @@ async function proxyChatViaResponses(
331
336
  * Responses / Open Responses surface (model stays in the body; URL is
332
337
  * workspace-level). Streaming and non-streaming both pass through as-is.
333
338
  *
334
- * Open Responses (Claude/Gemini/…) only accepts `function` tools, so Codex's
335
- * built-in `web_search` / `local_shell` / are stripped there. The OpenAI
336
- * `/responses` path keeps them - GPT models support those tool types.
339
+ * Open Responses (Claude/Gemini/…) only accepts `function` tools and
340
+ * `input_*` content part types, and rejects replayed Claude thinking
341
+ * blocks so Codex's built-in tools, prior-turn `output_text`, and
342
+ * `redacted_thinking` / `thinking` / `reasoning` parts are rewritten or
343
+ * stripped there. The OpenAI `/responses` path keeps them - GPT supports
344
+ * those shapes.
337
345
  */
338
346
  async function handleResponses(
339
347
  backend: DatabricksBackend,
@@ -351,10 +359,10 @@ async function handleResponses(
351
359
  body.model = resolved.modelId;
352
360
 
353
361
  const upstreamUrl = backend.responsesUrl(resolved.modelId);
354
- // Cross-provider Open Responses rejects non-function tool types; OpenAI
355
- // `/responses` keeps Codex built-ins (web_search, local_shell, custom, …).
362
+ // Cross-provider Open Responses rejects non-function tools and `output_*`
363
+ // content parts in `input`; OpenAI `/responses` keeps Codex's native shapes.
356
364
  const forward = upstreamUrl.includes("/open-responses")
357
- ? sanitizeResponsesTools(body)
365
+ ? sanitizeOpenResponsesRequest(body)
358
366
  : body;
359
367
 
360
368
  const wantsStream = forward.stream === true;