@kenkaiiii/gg-ai 5.66.2 → 5.66.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/dist/index.js CHANGED
@@ -2684,6 +2684,8 @@ async function* runStream3(options, retriedWithoutReasoning = false) {
2684
2684
  const contentParts = [];
2685
2685
  let textAccum = "";
2686
2686
  const toolCalls = /* @__PURE__ */ new Map();
2687
+ const finishedToolCalls = /* @__PURE__ */ new Set();
2688
+ let terminal;
2687
2689
  const orderedItems = [];
2688
2690
  const outputItemTypes = /* @__PURE__ */ new Map();
2689
2691
  const outputTextByPart = /* @__PURE__ */ new Map();
@@ -2827,6 +2829,7 @@ async function* runStream3(options, retriedWithoutReasoning = false) {
2827
2829
  for (const [key, tc] of toolCalls) {
2828
2830
  if (key.endsWith(`|${itemId}`)) {
2829
2831
  tc.argsJson = argsStr;
2832
+ finishedToolCalls.add(key);
2830
2833
  break;
2831
2834
  }
2832
2835
  }
@@ -2852,6 +2855,7 @@ async function* runStream3(options, retriedWithoutReasoning = false) {
2852
2855
  const id = `${callId}|${itemId}`;
2853
2856
  const tc = toolCalls.get(id);
2854
2857
  if (tc) {
2858
+ finishedToolCalls.add(id);
2855
2859
  orderedItems.push({ kind: "tool", id });
2856
2860
  const args = parseToolArguments(tc.argsJson);
2857
2861
  yield {
@@ -2863,8 +2867,17 @@ async function* runStream3(options, retriedWithoutReasoning = false) {
2863
2867
  }
2864
2868
  }
2865
2869
  }
2866
- if (type === "response.completed" || type === "response.done") {
2870
+ if (type === "response.completed" || type === "response.done" || type === "response.incomplete") {
2867
2871
  const resp = event.response;
2872
+ if (type === "response.incomplete" || resp?.status === "incomplete") {
2873
+ const details = resp?.incomplete_details;
2874
+ terminal = {
2875
+ status: "incomplete",
2876
+ reason: typeof details?.reason === "string" ? details.reason : void 0
2877
+ };
2878
+ } else {
2879
+ terminal = { status: "completed" };
2880
+ }
2868
2881
  const usage = resp?.usage;
2869
2882
  if (usage) {
2870
2883
  cacheRead = usage.input_tokens_details?.cached_tokens ?? 0;
@@ -2874,6 +2887,25 @@ async function* runStream3(options, retriedWithoutReasoning = false) {
2874
2887
  }
2875
2888
  }
2876
2889
  }
2890
+ if (!terminal) {
2891
+ throw new ProviderError("openai", "Stream ended before completion (no response.completed).", {
2892
+ statusCode: 504
2893
+ });
2894
+ }
2895
+ const droppedToolCalls = [...toolCalls.keys()].filter((id) => !finishedToolCalls.has(id)).length;
2896
+ if (terminal.status === "completed") {
2897
+ for (const [id, tc] of toolCalls) {
2898
+ if (!finishedToolCalls.has(id)) {
2899
+ throw new ProviderError(
2900
+ "openai",
2901
+ `Codex reply completed with an unfinished tool call: ${tc.name} (${id}).`,
2902
+ { statusCode: 502 }
2903
+ );
2904
+ }
2905
+ }
2906
+ } else {
2907
+ providerDiag("codex_incomplete", { reason: terminal.reason ?? null, droppedToolCalls });
2908
+ }
2877
2909
  const seenTool = /* @__PURE__ */ new Set();
2878
2910
  let textInserted = false;
2879
2911
  for (const entry of orderedItems) {
@@ -2900,7 +2932,7 @@ async function* runStream3(options, retriedWithoutReasoning = false) {
2900
2932
  contentParts.push({ type: "text", text: textAccum });
2901
2933
  }
2902
2934
  for (const [id, tc] of toolCalls) {
2903
- if (seenTool.has(id)) continue;
2935
+ if (seenTool.has(id) || !finishedToolCalls.has(id)) continue;
2904
2936
  seenTool.add(id);
2905
2937
  contentParts.push({
2906
2938
  type: "tool_call",
@@ -2909,8 +2941,15 @@ async function* runStream3(options, retriedWithoutReasoning = false) {
2909
2941
  args: parseToolArguments(tc.argsJson)
2910
2942
  });
2911
2943
  }
2944
+ if (droppedToolCalls > 0) {
2945
+ let last = contentParts.at(-1);
2946
+ while (last?.type === "raw" && isEncryptedReasoning(last.data)) {
2947
+ contentParts.pop();
2948
+ last = contentParts.at(-1);
2949
+ }
2950
+ }
2912
2951
  const hasToolCalls = contentParts.some((p) => p.type === "tool_call");
2913
- const stopReason = hasToolCalls ? "tool_use" : "end_turn";
2952
+ const stopReason = terminal.status === "incomplete" ? incompleteStopReason(terminal.reason) : hasToolCalls ? "tool_use" : "end_turn";
2914
2953
  const streamResponse = {
2915
2954
  message: {
2916
2955
  role: "assistant",
@@ -2927,6 +2966,11 @@ async function* runStream3(options, retriedWithoutReasoning = false) {
2927
2966
  yield { type: "done", stopReason };
2928
2967
  return streamResponse;
2929
2968
  }
2969
+ function incompleteStopReason(reason) {
2970
+ if (reason === "max_output_tokens") return "max_tokens";
2971
+ if (reason === "content_filter") return "refusal";
2972
+ return "error";
2973
+ }
2930
2974
  async function* parseSSE(body) {
2931
2975
  for await (const event of readSseStream(body)) {
2932
2976
  const data = event.data.trim();
@@ -4056,6 +4100,8 @@ var CIRCULAR = "[CIRCULAR]";
4056
4100
  var SENSITIVE_NAME = /(?:^|[_-])(?:api[_-]?key|access[_-]?token|refresh[_-]?token|token|key|auth(?:orization)?|bearer|cookie|credential|private[_-]?key|password|passwd|secret)(?:$|[_-])/i;
4057
4101
  var ENV_SECRET_ASSIGNMENT = /\b((?:[A-Z0-9]+_)*(?:API_?KEY|ACCESS_TOKEN|REFRESH_TOKEN|TOKEN|KEY|AUTH|AUTHORIZATION|BEARER|CREDENTIALS?|PASSWORD|PASSWD|SECRET))\b(\s*[=:]\s*)(["']?)(?!\$|process\.env|os\.environ|import\.meta|env\.)(?=[^\s,"';}]*\d)([^\s,"';}=$][^\s,"';}]{7,})\3/g;
4058
4102
  var COMPACT_SECRET_ASSIGNMENT = /\b((?:[a-z0-9]+[_-])*(?:api[_-]?key|access[_-]?token|refresh[_-]?token|token|auth|authorization|credentials?|password|passwd|secret)|(?:[a-z0-9]+[_-])+key)=(["']?)(?!\$)([^\s,"'&;}=][^\s,"'&;}]{7,})\2/gi;
4103
+ var URL_USERINFO = /\b([a-z][a-z0-9+.-]*:\/\/)[^\s/?#@:"'`<>]*:[^\s/?#"'`<>]+@/gi;
4104
+ var URL_USERINFO_TO_FIRST_AT = /\b([a-z][a-z0-9+.-]*:\/\/)[^\s/@:]*:[^\s/@]+@/gi;
4059
4105
  function escaped(value) {
4060
4106
  return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
4061
4107
  }
@@ -4079,7 +4125,8 @@ function redactText(text, options = {}) {
4079
4125
  /-----BEGIN (?:[A-Z0-9 ]+ )?PRIVATE KEY-----[\s\S]*?-----END (?:[A-Z0-9 ]+ )?PRIVATE KEY-----/g,
4080
4126
  REDACTED
4081
4127
  );
4082
- result = result.replace(/\b([a-z][a-z0-9+.-]*:\/\/)[^\s/@:]+:[^\s/@]+@/gi, `$1${REDACTED}@`);
4128
+ result = result.replace(URL_USERINFO, `$1${REDACTED}@`);
4129
+ result = result.replace(URL_USERINFO_TO_FIRST_AT, `$1${REDACTED}@`);
4083
4130
  result = result.replace(
4084
4131
  /\b(authorization\s*[:=]\s*)(?:bearer|basic)\s+[^\s,;]+/gi,
4085
4132
  `$1${REDACTED}`