@kenkaiiii/gg-ai 5.66.2 → 5.66.3

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.cjs CHANGED
@@ -2751,6 +2751,8 @@ async function* runStream3(options, retriedWithoutReasoning = false) {
2751
2751
  const contentParts = [];
2752
2752
  let textAccum = "";
2753
2753
  const toolCalls = /* @__PURE__ */ new Map();
2754
+ const finishedToolCalls = /* @__PURE__ */ new Set();
2755
+ let terminal;
2754
2756
  const orderedItems = [];
2755
2757
  const outputItemTypes = /* @__PURE__ */ new Map();
2756
2758
  const outputTextByPart = /* @__PURE__ */ new Map();
@@ -2894,6 +2896,7 @@ async function* runStream3(options, retriedWithoutReasoning = false) {
2894
2896
  for (const [key, tc] of toolCalls) {
2895
2897
  if (key.endsWith(`|${itemId}`)) {
2896
2898
  tc.argsJson = argsStr;
2899
+ finishedToolCalls.add(key);
2897
2900
  break;
2898
2901
  }
2899
2902
  }
@@ -2919,6 +2922,7 @@ async function* runStream3(options, retriedWithoutReasoning = false) {
2919
2922
  const id = `${callId}|${itemId}`;
2920
2923
  const tc = toolCalls.get(id);
2921
2924
  if (tc) {
2925
+ finishedToolCalls.add(id);
2922
2926
  orderedItems.push({ kind: "tool", id });
2923
2927
  const args = parseToolArguments(tc.argsJson);
2924
2928
  yield {
@@ -2930,8 +2934,17 @@ async function* runStream3(options, retriedWithoutReasoning = false) {
2930
2934
  }
2931
2935
  }
2932
2936
  }
2933
- if (type === "response.completed" || type === "response.done") {
2937
+ if (type === "response.completed" || type === "response.done" || type === "response.incomplete") {
2934
2938
  const resp = event.response;
2939
+ if (type === "response.incomplete" || resp?.status === "incomplete") {
2940
+ const details = resp?.incomplete_details;
2941
+ terminal = {
2942
+ status: "incomplete",
2943
+ reason: typeof details?.reason === "string" ? details.reason : void 0
2944
+ };
2945
+ } else {
2946
+ terminal = { status: "completed" };
2947
+ }
2935
2948
  const usage = resp?.usage;
2936
2949
  if (usage) {
2937
2950
  cacheRead = usage.input_tokens_details?.cached_tokens ?? 0;
@@ -2941,6 +2954,25 @@ async function* runStream3(options, retriedWithoutReasoning = false) {
2941
2954
  }
2942
2955
  }
2943
2956
  }
2957
+ if (!terminal) {
2958
+ throw new ProviderError("openai", "Stream ended before completion (no response.completed).", {
2959
+ statusCode: 504
2960
+ });
2961
+ }
2962
+ const droppedToolCalls = [...toolCalls.keys()].filter((id) => !finishedToolCalls.has(id)).length;
2963
+ if (terminal.status === "completed") {
2964
+ for (const [id, tc] of toolCalls) {
2965
+ if (!finishedToolCalls.has(id)) {
2966
+ throw new ProviderError(
2967
+ "openai",
2968
+ `Codex reply completed with an unfinished tool call: ${tc.name} (${id}).`,
2969
+ { statusCode: 502 }
2970
+ );
2971
+ }
2972
+ }
2973
+ } else {
2974
+ providerDiag("codex_incomplete", { reason: terminal.reason ?? null, droppedToolCalls });
2975
+ }
2944
2976
  const seenTool = /* @__PURE__ */ new Set();
2945
2977
  let textInserted = false;
2946
2978
  for (const entry of orderedItems) {
@@ -2967,7 +2999,7 @@ async function* runStream3(options, retriedWithoutReasoning = false) {
2967
2999
  contentParts.push({ type: "text", text: textAccum });
2968
3000
  }
2969
3001
  for (const [id, tc] of toolCalls) {
2970
- if (seenTool.has(id)) continue;
3002
+ if (seenTool.has(id) || !finishedToolCalls.has(id)) continue;
2971
3003
  seenTool.add(id);
2972
3004
  contentParts.push({
2973
3005
  type: "tool_call",
@@ -2976,8 +3008,15 @@ async function* runStream3(options, retriedWithoutReasoning = false) {
2976
3008
  args: parseToolArguments(tc.argsJson)
2977
3009
  });
2978
3010
  }
3011
+ if (droppedToolCalls > 0) {
3012
+ let last = contentParts.at(-1);
3013
+ while (last?.type === "raw" && isEncryptedReasoning(last.data)) {
3014
+ contentParts.pop();
3015
+ last = contentParts.at(-1);
3016
+ }
3017
+ }
2979
3018
  const hasToolCalls = contentParts.some((p) => p.type === "tool_call");
2980
- const stopReason = hasToolCalls ? "tool_use" : "end_turn";
3019
+ const stopReason = terminal.status === "incomplete" ? incompleteStopReason(terminal.reason) : hasToolCalls ? "tool_use" : "end_turn";
2981
3020
  const streamResponse = {
2982
3021
  message: {
2983
3022
  role: "assistant",
@@ -2994,6 +3033,11 @@ async function* runStream3(options, retriedWithoutReasoning = false) {
2994
3033
  yield { type: "done", stopReason };
2995
3034
  return streamResponse;
2996
3035
  }
3036
+ function incompleteStopReason(reason) {
3037
+ if (reason === "max_output_tokens") return "max_tokens";
3038
+ if (reason === "content_filter") return "refusal";
3039
+ return "error";
3040
+ }
2997
3041
  async function* parseSSE(body) {
2998
3042
  for await (const event of readSseStream(body)) {
2999
3043
  const data = event.data.trim();
@@ -4123,6 +4167,8 @@ var CIRCULAR = "[CIRCULAR]";
4123
4167
  var SENSITIVE_NAME = /(?:^|[_-])(?:api[_-]?key|access[_-]?token|refresh[_-]?token|token|key|auth(?:orization)?|bearer|cookie|credential|private[_-]?key|password|passwd|secret)(?:$|[_-])/i;
4124
4168
  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;
4125
4169
  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;
4170
+ var URL_USERINFO = /\b([a-z][a-z0-9+.-]*:\/\/)[^\s/?#@:"'`<>]*:[^\s/?#"'`<>]+@/gi;
4171
+ var URL_USERINFO_TO_FIRST_AT = /\b([a-z][a-z0-9+.-]*:\/\/)[^\s/@:]*:[^\s/@]+@/gi;
4126
4172
  function escaped(value) {
4127
4173
  return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
4128
4174
  }
@@ -4146,7 +4192,8 @@ function redactText(text, options = {}) {
4146
4192
  /-----BEGIN (?:[A-Z0-9 ]+ )?PRIVATE KEY-----[\s\S]*?-----END (?:[A-Z0-9 ]+ )?PRIVATE KEY-----/g,
4147
4193
  REDACTED
4148
4194
  );
4149
- result = result.replace(/\b([a-z][a-z0-9+.-]*:\/\/)[^\s/@:]+:[^\s/@]+@/gi, `$1${REDACTED}@`);
4195
+ result = result.replace(URL_USERINFO, `$1${REDACTED}@`);
4196
+ result = result.replace(URL_USERINFO_TO_FIRST_AT, `$1${REDACTED}@`);
4150
4197
  result = result.replace(
4151
4198
  /\b(authorization\s*[:=]\s*)(?:bearer|basic)\s+[^\s,;]+/gi,
4152
4199
  `$1${REDACTED}`