From abd97295345408d06f83ef7e3bc41b9394879548 Mon Sep 17 00:00:00 2001 From: askalf <263217947+askalf@users.noreply.github.com> Date: Tue, 22 Sep 2026 18:53:16 -0400 Subject: [PATCH] release: 0.3.0 The OpenAI Responses API (#70) moves from Unreleased to 0.3.0. It is also the first image since 0.2.0, so it carries 0.2.1's dependency update, which was never tagged or imaged. package.json and the lockfile's own version move to 0.3.0 so release.yml accepts the v0.3.0 tag; the release notes extract as the 0.3.0 section alone (scripts/release-notes.mjs 0.3.0). --- CHANGELOG.md | 4 ++++ package-lock.json | 4 ++-- package.json | 2 +- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c34ec51..9e60e00 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,10 @@ image and creates the GitHub release from this file. ## [Unreleased] +## [0.3.0] - 2026-09-22 + +The first image since 0.2.0: it also carries 0.2.1's dependency update, which was never tagged or published as an image. + ### Added - `POST /v1/responses` (the OpenAI Responses API) is redacted like `/v1/chat/completions`. Current OpenAI clients (`client.responses.create`, the Agents SDK, Codex) use it by default, and until now it passed through verbatim, so a modern OpenAI client pointed at cordon sent raw PII upstream with `X-Redacted: 0`. The request walk covers `instructions` (under `REDACT_SYSTEM`, with `system` and `developer` items), `input` as a string or an item list (`input_text` parts, `function_call` arguments as parsed JSON, `function_call_output` text) and flat function tool definitions; `input_image` and `input_file` parts are left untouched. Non-streaming replies restore `output_text` and `refusal` parts; streaming restores `response.output_text.delta` and `response.refusal.delta` under their own event kind, giving EACH content part its own hold-back buffer keyed by `item_id` / `output_index` / `content_index` (parts of one turn interleave on the wire, and one shared buffer spliced their text together). A part is flushed on its own done frame; `output_item.done` flushes only the item it names; `response.completed` / `incomplete` / `failed`, `[DONE]`, a reader error and an upstream that stops without any terminal frame all flush whatever is still held. The full text carried by `output_text.done`, `content_part.done`, `output_item.done` and `response.completed` is restored in place. Prior assistant turns fed back as input (`output_text` and `refusal` parts) are redacted too: a stateless client appends the previous reply, which cordon had already restored. Same modes, headers and audit record (provider `openai`). Sub-paths such as `/v1/responses/{id}` still pass through verbatim. diff --git a/package-lock.json b/package-lock.json index 0f11f65..793e142 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "cordon", - "version": "0.2.1", + "version": "0.3.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "cordon", - "version": "0.2.1", + "version": "0.3.0", "license": "MIT", "dependencies": { "fastify": "^5.12.5" diff --git a/package.json b/package.json index e02f597..c2ff56a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cordon", - "version": "0.2.1", + "version": "0.3.0", "private": true, "description": "cordon — a PII-redacting LLM compliance gateway. OpenAI/Anthropic-compatible. \"own your prompts — PII never leaves your perimeter.\"", "type": "module",