@linxiraos/pi-ai 1.2.1 → 1.3.0

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 (148) hide show
  1. package/CHANGELOG.md +83 -0
  2. package/README.md +4 -2
  3. package/THIRD-PARTY-NOTICES.txt +55 -5
  4. package/dist/types/auth/cascade.d.ts +5 -3
  5. package/dist/types/auth/pool.d.ts +3 -3
  6. package/dist/types/auth/select.d.ts +5 -1
  7. package/dist/types/auth/types.d.ts +15 -5
  8. package/dist/types/auth/usage-cache.d.ts +3 -1
  9. package/dist/types/auth-gateway/clients.d.ts +67 -0
  10. package/dist/types/auth-gateway/dispatch.d.ts +28 -10
  11. package/dist/types/auth-gateway/http.d.ts +2 -0
  12. package/dist/types/auth-gateway/index.d.ts +1 -0
  13. package/dist/types/auth-gateway/server.d.ts +9 -4
  14. package/dist/types/auth-gateway/session-state.d.ts +6 -0
  15. package/dist/types/auth-gateway/types.d.ts +16 -2
  16. package/dist/types/dialect/coercion.d.ts +6 -0
  17. package/dist/types/error/classes.d.ts +1 -1
  18. package/dist/types/error/flags.d.ts +15 -0
  19. package/dist/types/error/index.d.ts +1 -0
  20. package/dist/types/error/network-cause.d.ts +40 -0
  21. package/dist/types/images/shared.d.ts +26 -2
  22. package/dist/types/index.d.ts +1 -0
  23. package/dist/types/judgment/native.d.ts +51 -3
  24. package/dist/types/judgment/systemone.d.ts +9 -2
  25. package/dist/types/judgment/text.d.ts +11 -5
  26. package/dist/types/judgment/types.d.ts +5 -1
  27. package/dist/types/judgment/wire.d.ts +16 -3
  28. package/dist/types/provider-session-state.d.ts +2 -2
  29. package/dist/types/providers/anthropic-images.d.ts +7 -0
  30. package/dist/types/providers/anthropic-signature.d.ts +12 -2
  31. package/dist/types/providers/anthropic-state.d.ts +7 -0
  32. package/dist/types/providers/anthropic.d.ts +21 -6
  33. package/dist/types/providers/connection-prewarm.d.ts +15 -0
  34. package/dist/types/providers/cursor/exec-modern.d.ts +1 -1
  35. package/dist/types/providers/cursor-pi-args.d.ts +13 -0
  36. package/dist/types/providers/cursor.d.ts +7 -0
  37. package/dist/types/providers/openai-codex-responses.d.ts +6 -0
  38. package/dist/types/providers/openai-responses.d.ts +9 -0
  39. package/dist/types/providers/openai-shared.d.ts +30 -0
  40. package/dist/types/providers/systemone-server.d.ts +7 -3
  41. package/dist/types/providers/transform-messages.d.ts +26 -5
  42. package/dist/types/registry/oauth/google-antigravity.d.ts +1 -1
  43. package/dist/types/stream.d.ts +0 -2
  44. package/dist/types/types.d.ts +33 -9
  45. package/dist/types/utils/dsml-leak.d.ts +4 -2
  46. package/dist/types/utils/narration.d.ts +9 -0
  47. package/dist/types/utils/openai-http.d.ts +2 -0
  48. package/dist/types/utils/request-body.d.ts +11 -0
  49. package/dist/types/utils/request-compression.d.ts +21 -0
  50. package/dist/types/utils/tool-call-arguments.d.ts +2 -1
  51. package/dist/types/utils/transport-fetch.d.ts +8 -0
  52. package/dist/types/utils.d.ts +1 -1
  53. package/package.json +7 -7
  54. package/src/auth/cascade.ts +23 -13
  55. package/src/auth/pool.ts +3 -3
  56. package/src/auth/refresh.ts +39 -12
  57. package/src/auth/select.ts +8 -2
  58. package/src/auth/types.ts +16 -5
  59. package/src/auth/usage-cache.ts +23 -7
  60. package/src/auth/usage.ts +2 -4
  61. package/src/auth-broker/remote-store.ts +31 -6
  62. package/src/auth-gateway/clients.ts +318 -0
  63. package/src/auth-gateway/dispatch.ts +66 -35
  64. package/src/auth-gateway/http.ts +11 -5
  65. package/src/auth-gateway/index.ts +1 -0
  66. package/src/auth-gateway/routes/embeddings.ts +4 -10
  67. package/src/auth-gateway/routes/images.ts +6 -10
  68. package/src/auth-gateway/routes/rerank.ts +4 -10
  69. package/src/auth-gateway/routes/speech.ts +10 -10
  70. package/src/auth-gateway/routes/systemone.ts +22 -12
  71. package/src/auth-gateway/routes/transcriptions.ts +4 -2
  72. package/src/auth-gateway/routes/video.ts +12 -15
  73. package/src/auth-gateway/server.ts +136 -53
  74. package/src/auth-gateway/session-state.ts +14 -0
  75. package/src/auth-gateway/types.ts +16 -2
  76. package/src/dialect/coercion.ts +16 -0
  77. package/src/dialect/hermes.ts +7 -11
  78. package/src/dialect/qwen3.ts +3 -11
  79. package/src/error/classes.ts +3 -2
  80. package/src/error/flags.ts +24 -3
  81. package/src/error/index.ts +1 -0
  82. package/src/error/network-cause.ts +179 -0
  83. package/src/images/codex-format-directive.md +3 -0
  84. package/src/images/google-antigravity.ts +2 -1
  85. package/src/images/google-generative-ai.ts +4 -2
  86. package/src/images/openai-hosted.ts +25 -2
  87. package/src/images/openai-images.ts +11 -6
  88. package/src/images/shared.ts +77 -3
  89. package/src/index.ts +1 -0
  90. package/src/judgment/chat.ts +17 -1
  91. package/src/judgment/native.ts +182 -12
  92. package/src/judgment/openai-decisions.ts +27 -6
  93. package/src/judgment/systemone.ts +131 -10
  94. package/src/judgment/text.ts +20 -7
  95. package/src/judgment/types.ts +5 -1
  96. package/src/judgment/wire.ts +17 -3
  97. package/src/provider-session-state.ts +2 -2
  98. package/src/providers/amazon-bedrock.ts +4 -1
  99. package/src/providers/anthropic-client.ts +1 -1
  100. package/src/providers/anthropic-images.ts +263 -0
  101. package/src/providers/anthropic-messages-server.ts +84 -1
  102. package/src/providers/anthropic-signature.ts +35 -8
  103. package/src/providers/anthropic-state.ts +13 -0
  104. package/src/providers/anthropic.ts +479 -397
  105. package/src/providers/connection-prewarm.ts +78 -0
  106. package/src/providers/cowork-fetch.ts +5 -1
  107. package/src/providers/cursor/exec-modern.ts +1 -0
  108. package/src/providers/cursor-pi-args.ts +19 -0
  109. package/src/providers/cursor.ts +53 -13
  110. package/src/providers/devin.ts +10 -4
  111. package/src/providers/factory-droid/gemini.ts +9 -3
  112. package/src/providers/google-gemini-cli.ts +11 -1
  113. package/src/providers/google-shared.ts +2 -6
  114. package/src/providers/images-server.ts +6 -1
  115. package/src/providers/ollama.ts +15 -5
  116. package/src/providers/openai-anthropic-shim.ts +1 -0
  117. package/src/providers/openai-chat-server.ts +29 -0
  118. package/src/providers/openai-codex/access-programs.ts +2 -1
  119. package/src/providers/openai-codex-responses.ts +49 -82
  120. package/src/providers/openai-completions.ts +117 -19
  121. package/src/providers/openai-responses.ts +25 -2
  122. package/src/providers/openai-shared.ts +36 -5
  123. package/src/providers/pi-native-server.ts +1 -0
  124. package/src/providers/systemone-server.ts +72 -12
  125. package/src/providers/transform-messages.ts +95 -51
  126. package/src/registry/oauth/google-antigravity.ts +1 -1
  127. package/src/stream.ts +13 -73
  128. package/src/types.ts +33 -9
  129. package/src/usage/claude.ts +2 -9
  130. package/src/usage/github-copilot.ts +26 -4
  131. package/src/usage/openai-codex.ts +13 -7
  132. package/src/usage/opencode-go.ts +7 -8
  133. package/src/usage/xai-oauth.ts +2 -9
  134. package/src/utils/dsml-leak.ts +30 -14
  135. package/src/utils/leaked-thinking-stream.ts +10 -0
  136. package/src/utils/narration.ts +18 -0
  137. package/src/utils/openai-http.ts +27 -18
  138. package/src/utils/request-body.ts +27 -0
  139. package/src/utils/request-compression.ts +202 -0
  140. package/src/utils/request-debug.ts +23 -9
  141. package/src/utils/schema/dereference.ts +51 -18
  142. package/src/utils/schema/draft.ts +10 -2
  143. package/src/utils/schema/json-schema-validator.ts +4 -10
  144. package/src/utils/schema/normalize.ts +6 -9
  145. package/src/utils/tool-call-arguments.ts +2 -1
  146. package/src/utils/transport-fetch.ts +37 -0
  147. package/src/utils/validation.ts +26 -16
  148. package/src/utils.ts +38 -23
package/src/utils.ts CHANGED
@@ -1,7 +1,9 @@
1
1
  import { $env } from "@linxiraos/pi-utils";
2
2
  import type { ResponseInput, ResponseInputItem } from "./providers/openai-responses-wire";
3
3
  import { isMalformedToolCallName, redactSensitiveCredentials } from "./providers/transform-messages";
4
+ export { normalizeToolCallId } from "./providers/transform-messages";
4
5
  import type { CacheRetention, OpenAIResponsesHistoryPayload, ProviderPayload } from "./types";
6
+ import { invalidToolCallArguments } from "./utils/tool-call-arguments";
5
7
 
6
8
  type OpenAIResponsesReplayItem = ResponseInput[number];
7
9
  const NON_WHITESPACE_RE = /\S/;
@@ -33,11 +35,6 @@ export function normalizeSystemPrompts(systemPrompt: readonly string[] | string
33
35
  .filter(prompt => prompt.trim().length > 0);
34
36
  }
35
37
 
36
- export function normalizeToolCallId(id: string): string {
37
- const sanitized = id.replace(/[^a-zA-Z0-9_-]/g, "_");
38
- return sanitized.length > 64 ? sanitized.slice(0, 64) : sanitized;
39
- }
40
-
41
38
  type ResponsesToolItemIdPrefix = "fc" | "ctc";
42
39
 
43
40
  /** Preserve opaque call IDs for Responses replay while normalizing or generating the separate item ID. */
@@ -561,24 +558,44 @@ export function dropMalformedOpenAIResponsesToolCalls<
561
558
  }
562
559
 
563
560
  /**
564
- * Replay history is immutable and re-sanitized on every request, so remember
565
- * which `arguments` string each item was already validated with instead of
561
+ * Replay history is immutable and re-sanitized on every request, so each item
562
+ * remembers the replay `arguments` derived from its stored value instead of
566
563
  * re-parsing every historical call (large write/edit payloads) per request.
564
+ * Frozen/sealed caller-owned items are never mutated; they re-parse instead.
565
+ */
566
+ const kReplayArguments = Symbol("openaiResponses.replayArguments");
567
+
568
+ interface FunctionCallReplayItem extends Record<string, unknown> {
569
+ [kReplayArguments]?: { raw: unknown; replay: string };
570
+ }
571
+
572
+ /**
573
+ * `arguments` to replay for a native `function_call`: the stored string when it
574
+ * parses, `{}` when absent/blank, else the bounded `{__parseError, __rawJson}`
575
+ * diagnostic the transcript (and the cold replay path) already carries.
576
+ *
577
+ * Unparsable text (stream cut off mid-JSON) 400s the whole request, but dropping
578
+ * the call orphans its recorded tool result into an assistant note that can end
579
+ * the request and 400 it again (#15568).
567
580
  */
568
- const validatedReplayArguments = new WeakMap<object, string>();
569
-
570
- function hasValidReplayArguments(item: Record<string, unknown>): boolean {
571
- const args = item.arguments;
572
- if (typeof args !== "string") return false;
573
- if (validatedReplayArguments.get(item) === args) return true;
574
- if (args.trim().length === 0) return false;
575
- try {
576
- JSON.parse(args);
577
- } catch {
578
- return false;
581
+ function replayFunctionCallArguments(item: FunctionCallReplayItem): string {
582
+ const raw = item.arguments;
583
+ const cached = item[kReplayArguments];
584
+ if (cached && cached.raw === raw) return cached.replay;
585
+ let replay = "{}";
586
+ if (typeof raw === "string" && raw.trim().length > 0) {
587
+ try {
588
+ JSON.parse(raw);
589
+ replay = raw;
590
+ } catch (error) {
591
+ replay = JSON.stringify(invalidToolCallArguments(raw, error));
592
+ }
579
593
  }
580
- validatedReplayArguments.set(item, args);
581
- return true;
594
+ // Non-enumerable: the sanitizer's object rest copy must not carry the cache onto wire items.
595
+ if (Object.isExtensible(item)) {
596
+ Object.defineProperty(item, kReplayArguments, { value: { raw, replay }, writable: true });
597
+ }
598
+ return replay;
582
599
  }
583
600
 
584
601
  function sanitizeOpenAIResponsesHistoryItemForReplay(
@@ -592,9 +609,6 @@ function sanitizeOpenAIResponsesHistoryItemForReplay(
592
609
  if (isMalformedOpenAIResponsesToolCall(item)) {
593
610
  return undefined;
594
611
  }
595
- if (item.type === "function_call") {
596
- if (!hasValidReplayArguments(item)) return undefined;
597
- }
598
612
  if (item.type === "item_reference") return undefined;
599
613
  if (item.type === "image_generation_call") return sanitizeOpenAIResponsesImageGenerationCallForReplay(item);
600
614
  if (item.type === "reasoning") {
@@ -602,6 +616,7 @@ function sanitizeOpenAIResponsesHistoryItemForReplay(
602
616
  }
603
617
  const { id: _id, ...sanitizedItem } = item;
604
618
  if (item.type === "computer_call" && typeof item.id === "string") sanitizedItem.id = item.id;
619
+ if (item.type === "function_call") sanitizedItem.arguments = replayFunctionCallArguments(item);
605
620
 
606
621
  return clampReplayItemImageDetail(
607
622
  sanitizedItem,