jeopi-ai 16.4.3 → 16.4.4

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/CHANGELOG.md CHANGED
@@ -2,6 +2,12 @@
2
2
 
3
3
  ## [Unreleased]
4
4
 
5
+ ## [16.4.4] - 2026-08-03
6
+
7
+ ### Fixed
8
+
9
+ - Escaped OAuth callback state before embedding it in the HTML script payload, preventing callback error text from breaking out of the response document.
10
+
5
11
  ## [16.4.3] - 2026-07-22
6
12
 
7
13
  ### Added
@@ -385,6 +385,8 @@ export declare function appendReasoningSummaryTextDelta(item: ResponseReasoningI
385
385
  export declare function appendReasoningSummaryPartDone(item: ResponseReasoningItem, block: ThinkingContent, stream: AssistantMessageEventStream, output: AssistantMessage, contentIndex: number): void;
386
386
  export declare function appendMessageContentPart(item: ResponseOutputMessage, part: ResponseContentPartAddedEvent["part"] | undefined): void;
387
387
  export declare function appendMessageTextDelta(item: ResponseOutputMessage, block: TextContent, delta: string, stream: AssistantMessageEventStream, output: AssistantMessage, contentIndex: number, partType: "output_text" | "refusal"): void;
388
+ /** Chooses final message text while treating non-empty terminal content as authoritative. */
389
+ export declare function finalizeMessageText(item: ResponseOutputMessage, streamedText: string): string;
388
390
  export declare function accumulateToolCallArgumentsDelta(block: ResponsesToolCallBlock, delta: string, stream: AssistantMessageEventStream, output: AssistantMessage, contentIndex: number): void;
389
391
  /**
390
392
  * Finalize streamed function-call arguments from the authoritative `.done`
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "type": "module",
3
3
  "name": "jeopi-ai",
4
- "version": "16.4.3",
4
+ "version": "16.4.4",
5
5
  "description": "Unified LLM API with automatic model discovery and provider configuration",
6
6
  "homepage": "https://github.com/akillness/jeopi",
7
7
  "author": "Can Boluk",
@@ -38,9 +38,9 @@
38
38
  },
39
39
  "dependencies": {
40
40
  "@bufbuild/protobuf": "^2.12.0",
41
- "jeopi-catalog": "16.4.3",
42
- "jeopi-utils": "16.4.3",
43
- "jeopi-wire": "16.4.3",
41
+ "jeopi-catalog": "16.4.4",
42
+ "jeopi-utils": "16.4.4",
43
+ "jeopi-wire": "16.4.4",
44
44
  "arktype": "^2.2.0",
45
45
  "zod": "^4"
46
46
  },
@@ -86,6 +86,7 @@ import {
86
86
  encodeResponsesToolCallId,
87
87
  encodeTextSignatureV1,
88
88
  finalizeCustomToolCallInputDone,
89
+ finalizeMessageText,
89
90
  finalizePendingResponsesToolCalls,
90
91
  finalizeToolCallArgumentsDone,
91
92
  isOpenAIResponsesProgressEvent,
@@ -1458,9 +1459,7 @@ class CodexStreamProcessor {
1458
1459
  }
1459
1460
 
1460
1461
  if (item.type === "message" && block?.type === "text") {
1461
- block.text = item.content
1462
- .map(content => (content.type === "output_text" ? content.text : content.refusal))
1463
- .join("");
1462
+ block.text = finalizeMessageText(item, block.text);
1464
1463
  const phase = item.phase === "commentary" || item.phase === "final_answer" ? item.phase : undefined;
1465
1464
  block.textSignature = encodeTextSignatureV1(item.id, phase);
1466
1465
  stream.push({
@@ -1744,6 +1744,11 @@ export function appendMessageTextDelta(
1744
1744
  }
1745
1745
  stream.push({ type: "text_delta", contentIndex, delta, partial: output });
1746
1746
  }
1747
+ /** Chooses final message text while treating non-empty terminal content as authoritative. */
1748
+ export function finalizeMessageText(item: ResponseOutputMessage, streamedText: string): string {
1749
+ if (!item.content?.length) return streamedText || "";
1750
+ return item.content.map(part => (part.type === "output_text" ? (part.text ?? "") : (part.refusal ?? ""))).join("");
1751
+ }
1747
1752
 
1748
1753
  export function accumulateToolCallArgumentsDelta(
1749
1754
  block: ResponsesToolCallBlock,
@@ -2136,9 +2141,7 @@ export async function processResponsesStream<TApi extends Api>(
2136
2141
  closeOpenItem(event.output_index, item.id, entry);
2137
2142
  } else if (item.type === "message") {
2138
2143
  const block = entry?.block.type === "text" ? entry.block : undefined;
2139
- const text = item.content
2140
- .map(part => (part.type === "output_text" ? (part.text ?? "") : (part.refusal ?? "")))
2141
- .join("");
2144
+ const text = finalizeMessageText(item, block?.text ?? "");
2142
2145
  const textSignature = encodeTextSignatureV1(item.id, item.phase ?? undefined);
2143
2146
  let contentIndex: number;
2144
2147
  if (block) {
@@ -18,6 +18,26 @@ const DEFAULT_TIMEOUT = 300_000;
18
18
  const DEFAULT_HOSTNAME = "localhost";
19
19
  const CALLBACK_PATH = "/callback";
20
20
 
21
+ function escapeJsonForHtmlScript(value: object): string {
22
+ const json = JSON.stringify(value) ?? "null";
23
+ return json.replace(/[<>&\u2028\u2029]/g, character => {
24
+ switch (character) {
25
+ case "<":
26
+ return "\\u003C";
27
+ case ">":
28
+ return "\\u003E";
29
+ case "&":
30
+ return "\\u0026";
31
+ case "\u2028":
32
+ return "\\u2028";
33
+ case "\u2029":
34
+ return "\\u2029";
35
+ default:
36
+ return character;
37
+ }
38
+ });
39
+ }
40
+
21
41
  export type CallbackResult = { code: string; state: string };
22
42
 
23
43
  export interface OAuthCallbackFlowOptions {
@@ -230,7 +250,7 @@ export abstract class OAuthCallbackFlow {
230
250
  });
231
251
 
232
252
  return new Response(
233
- (templateHtml as unknown as string).replaceAll("__OAUTH_STATE__", JSON.stringify(resultState)),
253
+ (templateHtml as unknown as string).replaceAll("__OAUTH_STATE__", () => escapeJsonForHtmlScript(resultState)),
234
254
  {
235
255
  status: resultState.ok ? 200 : 500,
236
256
  headers: { "Content-Type": "text/html" },