@codemieai/code 0.12.0 → 0.13.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 (204) hide show
  1. package/README.md +109 -56
  2. package/bin/codemie-copilot.js +224 -0
  3. package/bin/codemie-pi.js +18 -0
  4. package/dist/agents/core/AgentCLI.d.ts.map +1 -1
  5. package/dist/agents/core/AgentCLI.js +16 -10
  6. package/dist/agents/core/AgentCLI.js.map +1 -1
  7. package/dist/agents/core/BaseAgentAdapter.d.ts.map +1 -1
  8. package/dist/agents/core/BaseAgentAdapter.js +43 -19
  9. package/dist/agents/core/BaseAgentAdapter.js.map +1 -1
  10. package/dist/agents/core/agent-aliases.d.ts +17 -0
  11. package/dist/agents/core/agent-aliases.d.ts.map +1 -0
  12. package/dist/agents/core/agent-aliases.js +41 -0
  13. package/dist/agents/core/agent-aliases.js.map +1 -0
  14. package/dist/agents/core/session/session-origin-audit.d.ts +13 -0
  15. package/dist/agents/core/session/session-origin-audit.d.ts.map +1 -1
  16. package/dist/agents/core/session/session-origin-audit.js +34 -0
  17. package/dist/agents/core/session/session-origin-audit.js.map +1 -1
  18. package/dist/agents/core/session/stale-session-reconciliation.d.ts +42 -0
  19. package/dist/agents/core/session/stale-session-reconciliation.d.ts.map +1 -0
  20. package/dist/agents/core/session/stale-session-reconciliation.js +141 -0
  21. package/dist/agents/core/session/stale-session-reconciliation.js.map +1 -0
  22. package/dist/agents/core/session/types.d.ts +19 -0
  23. package/dist/agents/core/session/types.d.ts.map +1 -1
  24. package/dist/agents/core/session/types.js +17 -1
  25. package/dist/agents/core/session/types.js.map +1 -1
  26. package/dist/agents/core/types.d.ts +1 -0
  27. package/dist/agents/core/types.d.ts.map +1 -1
  28. package/dist/agents/plugins/codex/codex.reconciliation.d.ts +15 -35
  29. package/dist/agents/plugins/codex/codex.reconciliation.d.ts.map +1 -1
  30. package/dist/agents/plugins/codex/codex.reconciliation.js +8 -139
  31. package/dist/agents/plugins/codex/codex.reconciliation.js.map +1 -1
  32. package/dist/agents/plugins/copilot-cli/copilot-cli.constants.d.ts +4 -0
  33. package/dist/agents/plugins/copilot-cli/copilot-cli.constants.d.ts.map +1 -1
  34. package/dist/agents/plugins/copilot-cli/copilot-cli.constants.js +4 -0
  35. package/dist/agents/plugins/copilot-cli/copilot-cli.constants.js.map +1 -1
  36. package/dist/agents/plugins/copilot-cli/copilot-cli.models.d.ts +8 -0
  37. package/dist/agents/plugins/copilot-cli/copilot-cli.models.d.ts.map +1 -0
  38. package/dist/agents/plugins/copilot-cli/copilot-cli.models.js +195 -0
  39. package/dist/agents/plugins/copilot-cli/copilot-cli.models.js.map +1 -0
  40. package/dist/agents/plugins/copilot-cli/copilot-cli.plugin.d.ts +4 -20
  41. package/dist/agents/plugins/copilot-cli/copilot-cli.plugin.d.ts.map +1 -1
  42. package/dist/agents/plugins/copilot-cli/copilot-cli.plugin.js +237 -38
  43. package/dist/agents/plugins/copilot-cli/copilot-cli.plugin.js.map +1 -1
  44. package/dist/agents/plugins/copilot-cli/copilot-cli.session.d.ts.map +1 -1
  45. package/dist/agents/plugins/copilot-cli/copilot-cli.session.js +14 -2
  46. package/dist/agents/plugins/copilot-cli/copilot-cli.session.js.map +1 -1
  47. package/dist/agents/plugins/copilot-cli/index.d.ts +2 -1
  48. package/dist/agents/plugins/copilot-cli/index.d.ts.map +1 -1
  49. package/dist/agents/plugins/copilot-cli/index.js +2 -1
  50. package/dist/agents/plugins/copilot-cli/index.js.map +1 -1
  51. package/dist/agents/plugins/copilot-cli/session/processors/copilot-cli.conversations-processor.d.ts +6 -3
  52. package/dist/agents/plugins/copilot-cli/session/processors/copilot-cli.conversations-processor.d.ts.map +1 -1
  53. package/dist/agents/plugins/copilot-cli/session/processors/copilot-cli.conversations-processor.js +298 -5
  54. package/dist/agents/plugins/copilot-cli/session/processors/copilot-cli.conversations-processor.js.map +1 -1
  55. package/dist/agents/plugins/pi/__tests__/home-redirect.d.ts +12 -0
  56. package/dist/agents/plugins/pi/__tests__/home-redirect.d.ts.map +1 -0
  57. package/dist/agents/plugins/pi/__tests__/home-redirect.js +27 -0
  58. package/dist/agents/plugins/pi/__tests__/home-redirect.js.map +1 -0
  59. package/dist/agents/plugins/pi/extension/README.md +68 -0
  60. package/dist/agents/plugins/pi/extension/index.js +161 -0
  61. package/dist/agents/plugins/pi/extension/package.json +8 -0
  62. package/dist/agents/plugins/pi/index.d.ts +3 -0
  63. package/dist/agents/plugins/pi/index.d.ts.map +1 -0
  64. package/dist/agents/plugins/pi/index.js +3 -0
  65. package/dist/agents/plugins/pi/index.js.map +1 -0
  66. package/dist/agents/plugins/pi/pi.extension.d.ts +60 -0
  67. package/dist/agents/plugins/pi/pi.extension.d.ts.map +1 -0
  68. package/dist/agents/plugins/pi/pi.extension.js +201 -0
  69. package/dist/agents/plugins/pi/pi.extension.js.map +1 -0
  70. package/dist/agents/plugins/pi/pi.incremental-sync.d.ts +63 -0
  71. package/dist/agents/plugins/pi/pi.incremental-sync.d.ts.map +1 -0
  72. package/dist/agents/plugins/pi/pi.incremental-sync.js +266 -0
  73. package/dist/agents/plugins/pi/pi.incremental-sync.js.map +1 -0
  74. package/dist/agents/plugins/pi/pi.models.d.ts +20 -0
  75. package/dist/agents/plugins/pi/pi.models.d.ts.map +1 -0
  76. package/dist/agents/plugins/pi/pi.models.js +201 -0
  77. package/dist/agents/plugins/pi/pi.models.js.map +1 -0
  78. package/dist/agents/plugins/pi/pi.packages.d.ts +11 -0
  79. package/dist/agents/plugins/pi/pi.packages.d.ts.map +1 -0
  80. package/dist/agents/plugins/pi/pi.packages.js +35 -0
  81. package/dist/agents/plugins/pi/pi.packages.js.map +1 -0
  82. package/dist/agents/plugins/pi/pi.paths.d.ts +37 -0
  83. package/dist/agents/plugins/pi/pi.paths.d.ts.map +1 -0
  84. package/dist/agents/plugins/pi/pi.paths.js +146 -0
  85. package/dist/agents/plugins/pi/pi.paths.js.map +1 -0
  86. package/dist/agents/plugins/pi/pi.plugin.d.ts +30 -0
  87. package/dist/agents/plugins/pi/pi.plugin.d.ts.map +1 -0
  88. package/dist/agents/plugins/pi/pi.plugin.js +453 -0
  89. package/dist/agents/plugins/pi/pi.plugin.js.map +1 -0
  90. package/dist/agents/plugins/pi/pi.session.d.ts +114 -0
  91. package/dist/agents/plugins/pi/pi.session.d.ts.map +1 -0
  92. package/dist/agents/plugins/pi/pi.session.js +388 -0
  93. package/dist/agents/plugins/pi/pi.session.js.map +1 -0
  94. package/dist/agents/plugins/pi/pi.setup.d.ts +2 -0
  95. package/dist/agents/plugins/pi/pi.setup.d.ts.map +1 -0
  96. package/dist/agents/plugins/pi/pi.setup.js +33 -0
  97. package/dist/agents/plugins/pi/pi.setup.js.map +1 -0
  98. package/dist/agents/plugins/pi/pi.types.d.ts +143 -0
  99. package/dist/agents/plugins/pi/pi.types.d.ts.map +1 -0
  100. package/dist/agents/plugins/pi/pi.types.js +74 -0
  101. package/dist/agents/plugins/pi/pi.types.js.map +1 -0
  102. package/dist/agents/plugins/pi/session/pi-file-operations.d.ts +17 -0
  103. package/dist/agents/plugins/pi/session/pi-file-operations.d.ts.map +1 -0
  104. package/dist/agents/plugins/pi/session/pi-file-operations.js +98 -0
  105. package/dist/agents/plugins/pi/session/pi-file-operations.js.map +1 -0
  106. package/dist/agents/plugins/pi/session/pi-named-invocations.d.ts +52 -0
  107. package/dist/agents/plugins/pi/session/pi-named-invocations.d.ts.map +1 -0
  108. package/dist/agents/plugins/pi/session/pi-named-invocations.js +189 -0
  109. package/dist/agents/plugins/pi/session/pi-named-invocations.js.map +1 -0
  110. package/dist/agents/plugins/pi/session/pi-user-prompt.d.ts +14 -0
  111. package/dist/agents/plugins/pi/session/pi-user-prompt.d.ts.map +1 -0
  112. package/dist/agents/plugins/pi/session/pi-user-prompt.js +51 -0
  113. package/dist/agents/plugins/pi/session/pi-user-prompt.js.map +1 -0
  114. package/dist/agents/plugins/pi/session/processors/pi.conversations-processor.d.ts +52 -0
  115. package/dist/agents/plugins/pi/session/processors/pi.conversations-processor.d.ts.map +1 -0
  116. package/dist/agents/plugins/pi/session/processors/pi.conversations-processor.js +716 -0
  117. package/dist/agents/plugins/pi/session/processors/pi.conversations-processor.js.map +1 -0
  118. package/dist/agents/plugins/pi/session/processors/pi.metrics-processor.d.ts +104 -0
  119. package/dist/agents/plugins/pi/session/processors/pi.metrics-processor.d.ts.map +1 -0
  120. package/dist/agents/plugins/pi/session/processors/pi.metrics-processor.js +595 -0
  121. package/dist/agents/plugins/pi/session/processors/pi.metrics-processor.js.map +1 -0
  122. package/dist/agents/registry.d.ts.map +1 -1
  123. package/dist/agents/registry.js +2 -2
  124. package/dist/agents/registry.js.map +1 -1
  125. package/dist/cli/commands/analytics/agent-labels.d.ts.map +1 -1
  126. package/dist/cli/commands/analytics/agent-labels.js +1 -0
  127. package/dist/cli/commands/analytics/agent-labels.js.map +1 -1
  128. package/dist/cli/commands/analytics/cost/usage-readers.d.ts +24 -0
  129. package/dist/cli/commands/analytics/cost/usage-readers.d.ts.map +1 -1
  130. package/dist/cli/commands/analytics/cost/usage-readers.js +199 -54
  131. package/dist/cli/commands/analytics/cost/usage-readers.js.map +1 -1
  132. package/dist/cli/commands/analytics/index.js +1 -0
  133. package/dist/cli/commands/analytics/index.js.map +1 -1
  134. package/dist/cli/commands/analytics/native-loader.d.ts +21 -4
  135. package/dist/cli/commands/analytics/native-loader.d.ts.map +1 -1
  136. package/dist/cli/commands/analytics/native-loader.js +250 -96
  137. package/dist/cli/commands/analytics/native-loader.js.map +1 -1
  138. package/dist/cli/commands/analytics/report/client/app.js +47 -3
  139. package/dist/cli/commands/analytics/report/payload-builder.d.ts.map +1 -1
  140. package/dist/cli/commands/analytics/report/payload-builder.js +25 -2
  141. package/dist/cli/commands/analytics/report/payload-builder.js.map +1 -1
  142. package/dist/cli/commands/analytics/report/types.d.ts +1 -0
  143. package/dist/cli/commands/analytics/report/types.d.ts.map +1 -1
  144. package/dist/cli/commands/hook.d.ts.map +1 -1
  145. package/dist/cli/commands/hook.js +71 -29
  146. package/dist/cli/commands/hook.js.map +1 -1
  147. package/dist/cli/commands/install.d.ts.map +1 -1
  148. package/dist/cli/commands/install.js +7 -5
  149. package/dist/cli/commands/install.js.map +1 -1
  150. package/dist/cli/commands/list.d.ts.map +1 -1
  151. package/dist/cli/commands/list.js +3 -1
  152. package/dist/cli/commands/list.js.map +1 -1
  153. package/dist/cli/commands/uninstall.d.ts.map +1 -1
  154. package/dist/cli/commands/uninstall.js +5 -3
  155. package/dist/cli/commands/uninstall.js.map +1 -1
  156. package/dist/cli/commands/update.d.ts.map +1 -1
  157. package/dist/cli/commands/update.js +5 -3
  158. package/dist/cli/commands/update.js.map +1 -1
  159. package/dist/cli/first-time.d.ts.map +1 -1
  160. package/dist/cli/first-time.js +7 -6
  161. package/dist/cli/first-time.js.map +1 -1
  162. package/dist/providers/core/auth-validation.d.ts +7 -2
  163. package/dist/providers/core/auth-validation.d.ts.map +1 -1
  164. package/dist/providers/core/auth-validation.js +11 -5
  165. package/dist/providers/core/auth-validation.js.map +1 -1
  166. package/dist/providers/plugins/sso/proxy/plugins/claude-request-normalizer.plugin.d.ts +8 -3
  167. package/dist/providers/plugins/sso/proxy/plugins/claude-request-normalizer.plugin.d.ts.map +1 -1
  168. package/dist/providers/plugins/sso/proxy/plugins/claude-request-normalizer.plugin.js +46 -11
  169. package/dist/providers/plugins/sso/proxy/plugins/claude-request-normalizer.plugin.js.map +1 -1
  170. package/dist/providers/plugins/sso/proxy/plugins/codex-encrypted-content-sanitizer.plugin.d.ts +23 -13
  171. package/dist/providers/plugins/sso/proxy/plugins/codex-encrypted-content-sanitizer.plugin.d.ts.map +1 -1
  172. package/dist/providers/plugins/sso/proxy/plugins/codex-encrypted-content-sanitizer.plugin.js +75 -18
  173. package/dist/providers/plugins/sso/proxy/plugins/codex-encrypted-content-sanitizer.plugin.js.map +1 -1
  174. package/dist/providers/plugins/sso/proxy/plugins/copilot-encrypted-content-sanitizer.plugin.d.ts +21 -0
  175. package/dist/providers/plugins/sso/proxy/plugins/copilot-encrypted-content-sanitizer.plugin.d.ts.map +1 -0
  176. package/dist/providers/plugins/sso/proxy/plugins/copilot-encrypted-content-sanitizer.plugin.js +133 -0
  177. package/dist/providers/plugins/sso/proxy/plugins/copilot-encrypted-content-sanitizer.plugin.js.map +1 -0
  178. package/dist/providers/plugins/sso/proxy/plugins/header-injection.plugin.js +1 -1
  179. package/dist/providers/plugins/sso/proxy/plugins/header-injection.plugin.js.map +1 -1
  180. package/dist/providers/plugins/sso/proxy/plugins/index.d.ts +2 -1
  181. package/dist/providers/plugins/sso/proxy/plugins/index.d.ts.map +1 -1
  182. package/dist/providers/plugins/sso/proxy/plugins/index.js +4 -2
  183. package/dist/providers/plugins/sso/proxy/plugins/index.js.map +1 -1
  184. package/dist/providers/plugins/sso/proxy/plugins/types.d.ts +11 -0
  185. package/dist/providers/plugins/sso/proxy/plugins/types.d.ts.map +1 -1
  186. package/dist/providers/plugins/sso/proxy/sso.proxy.d.ts +2 -0
  187. package/dist/providers/plugins/sso/proxy/sso.proxy.d.ts.map +1 -1
  188. package/dist/providers/plugins/sso/proxy/sso.proxy.js +37 -1
  189. package/dist/providers/plugins/sso/proxy/sso.proxy.js.map +1 -1
  190. package/dist/providers/plugins/sso/session/SessionSyncer.d.ts.map +1 -1
  191. package/dist/providers/plugins/sso/session/SessionSyncer.js +13 -0
  192. package/dist/providers/plugins/sso/session/SessionSyncer.js.map +1 -1
  193. package/dist/providers/plugins/sso/session/processors/conversations/syncProcessor.js +6 -0
  194. package/dist/providers/plugins/sso/session/processors/conversations/syncProcessor.js.map +1 -1
  195. package/dist/providers/plugins/sso/session/processors/metrics/metrics-post-processor.d.ts +0 -6
  196. package/dist/providers/plugins/sso/session/processors/metrics/metrics-post-processor.d.ts.map +1 -1
  197. package/dist/providers/plugins/sso/session/processors/metrics/metrics-post-processor.js +28 -19
  198. package/dist/providers/plugins/sso/session/processors/metrics/metrics-post-processor.js.map +1 -1
  199. package/dist/utils/interactive.d.ts +14 -0
  200. package/dist/utils/interactive.d.ts.map +1 -0
  201. package/dist/utils/interactive.js +16 -0
  202. package/dist/utils/interactive.js.map +1 -0
  203. package/package.json +6 -4
  204. package/scripts/copy-plugins.js +6 -0
@@ -1 +1 @@
1
- {"version":3,"file":"codex-encrypted-content-sanitizer.plugin.d.ts","sourceRoot":"","sources":["../../../../../../src/providers/plugins/sso/proxy/plugins/codex-encrypted-content-sanitizer.plugin.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAkB1E,qBAAa,oCAAqC,YAAW,WAAW;IACtE,EAAE,SAAsD;IACxD,IAAI,SAAuC;IAC3C,OAAO,SAAW;IAClB,QAAQ,SAAM;IAER,iBAAiB,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,gBAAgB,CAAC;CAQ3E"}
1
+ {"version":3,"file":"codex-encrypted-content-sanitizer.plugin.d.ts","sourceRoot":"","sources":["../../../../../../src/providers/plugins/sso/proxy/plugins/codex-encrypted-content-sanitizer.plugin.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAgC1E,qBAAa,oCAAqC,YAAW,WAAW;IACtE,EAAE,SAAsD;IACxD,IAAI,SAAuC;IAC3C,OAAO,SAAW;IAClB,QAAQ,SAAM;IAER,iBAAiB,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,gBAAgB,CAAC;CAQ3E"}
@@ -2,29 +2,52 @@
2
2
  * Encrypted Content Sanitizer
3
3
  * Priority: 16 (after generic request sanitizer, before header injection)
4
4
  *
5
- * LiteLLM/Azure can reject Responses API follow-up requests when encrypted
6
- * reasoning content is load-balanced to a different deployment/API key than
7
- * the one that created it. Server-side encrypted_content_affinity is the
8
- * correct fix. This client-side sanitizer is a defensive fallback:
9
- * it removes encrypted reasoning state so the session can continue instead of
10
- * failing with invalid_encrypted_content.
5
+ * Responses API reasoning items are bound to the deployment that produced them:
6
+ * `encrypted_content` is decryptable only by the API key that created it, and a
7
+ * bare `rs_...` id is unresolvable under `store: false`. Replaying either one
8
+ * against the wrong deployment fails the turn.
11
9
  *
12
- * Scope: codemie-codex, codemie-code, codemie-opencode, and vscode-byok. This
13
- * cross-client fallback covers Responses-API sessions when load balancing can
14
- * send encrypted state to a different deployment/API key. Tradeoff: drops
15
- * cross-turn hidden-reasoning continuity to avoid hard invalid_encrypted_content
16
- * failures while preserving effort, visible messages, and tool history. If
17
- * server-side encrypted_content_affinity becomes available, this client strip
18
- * becomes redundant.
10
+ * The gateway now runs LiteLLM `encrypted_content_affinity`, which routes a
11
+ * follow-up carrying encrypted content back to its originating deployment. So
12
+ * the default path is pass-through: reasoning state is forwarded untouched and
13
+ * agents keep full cross-turn reasoning continuity.
14
+ *
15
+ * Affinity pins expire (`deployment_affinity_ttl_seconds`), and a session
16
+ * resumed after expiry replays state no deployment can resolve. Because clients
17
+ * replay their whole history every turn, that first failure would otherwise
18
+ * repeat forever. This interceptor therefore watches upstream responses for the
19
+ * two failure signatures and, once either is seen, strips reasoning state from
20
+ * every subsequent request for the life of the proxy. The failing turn surfaces
21
+ * its error; the session then self-heals with degraded continuity instead of
22
+ * staying stuck.
23
+ *
24
+ * Stripping is the same trade as before: reasoning effort, visible messages,
25
+ * tool calls, and tool outputs survive; prior hidden reasoning does not.
26
+ *
27
+ * Scope: codemie-codex, codemie-code, codemie-opencode, codemie-pi, and
28
+ * vscode-byok.
19
29
  */
20
30
  import { logger } from '../../../../../utils/logger.js';
21
31
  const ALLOWED_AGENTS = [
22
32
  'codemie-codex',
23
33
  'codemie-code',
24
34
  'codemie-opencode',
35
+ 'codemie-pi',
25
36
  'vscode-byok',
26
37
  ];
27
38
  const ENCRYPTED_CONTENT_INCLUDE = 'reasoning.encrypted_content';
39
+ const RESPONSES_PATH_SUFFIX = '/responses';
40
+ /**
41
+ * Upstream signatures that mean replayed reasoning state was rejected:
42
+ * affinity miss or expired pin, and a bare reasoning id under `store: false`.
43
+ * Kept short so LiteLLM's nested JSON escaping cannot break the match.
44
+ */
45
+ const UNUSABLE_REASONING_STATE_MARKERS = [
46
+ 'invalid_encrypted_content',
47
+ 'Items are not persisted when',
48
+ ];
49
+ const MARKER_OVERLAP_BYTES = Math.max(...UNUSABLE_REASONING_STATE_MARKERS.map(m => m.length)) - 1;
50
+ const MARKER_CARRY_KEY = 'encryptedContentSanitizerMarkerCarry';
28
51
  export class CodexEncryptedContentSanitizerPlugin {
29
52
  id = '@codemie/proxy-codex-encrypted-content-sanitizer';
30
53
  name = 'Codex Encrypted Content Sanitizer';
@@ -41,10 +64,15 @@ export class CodexEncryptedContentSanitizerPlugin {
41
64
  class CodexEncryptedContentSanitizerInterceptor {
42
65
  clientType;
43
66
  name = 'codex-encrypted-content-sanitizer';
67
+ /** Set once upstream rejects replayed reasoning state; never cleared for this proxy. */
68
+ reasoningStateUnusable = false;
44
69
  constructor(clientType) {
45
70
  this.clientType = clientType;
46
71
  }
47
72
  async onRequest(context) {
73
+ if (!this.reasoningStateUnusable) {
74
+ return;
75
+ }
48
76
  if (!context.requestBody || !context.headers['content-type']?.includes('application/json')) {
49
77
  return;
50
78
  }
@@ -63,6 +91,30 @@ class CodexEncryptedContentSanitizerInterceptor {
63
91
  // Not valid JSON or unexpected structure — pass through unchanged.
64
92
  }
65
93
  }
94
+ /**
95
+ * Read-only scan of the upstream stream. Returns the chunk untouched; the only
96
+ * effect is latching `reasoningStateUnusable` so later requests get stripped.
97
+ */
98
+ async onResponseChunk(context, chunk) {
99
+ if (this.reasoningStateUnusable || !context.url.includes(RESPONSES_PATH_SUFFIX)) {
100
+ return chunk;
101
+ }
102
+ // Carry lives on the per-request context: concurrent streams must not share it.
103
+ const carry = context.metadata[MARKER_CARRY_KEY];
104
+ const searchable = Buffer.isBuffer(carry) ? Buffer.concat([carry, chunk]) : chunk;
105
+ const marker = UNUSABLE_REASONING_STATE_MARKERS.find(m => searchable.includes(m));
106
+ if (marker) {
107
+ this.reasoningStateUnusable = true;
108
+ delete context.metadata[MARKER_CARRY_KEY];
109
+ logger.warn(`[${this.name}] Upstream rejected replayed reasoning state for ${this.clientType} ("${marker}"). ` +
110
+ 'Stripping reasoning state from subsequent requests — cross-turn reasoning continuity is degraded ' +
111
+ 'for the rest of this session. Expected after an encrypted_content_affinity pin expires; ' +
112
+ 'a rising rate means deployment_affinity_ttl_seconds is too short.');
113
+ return chunk;
114
+ }
115
+ context.metadata[MARKER_CARRY_KEY] = searchable.subarray(Math.max(0, searchable.length - MARKER_OVERLAP_BYTES));
116
+ return chunk;
117
+ }
66
118
  }
67
119
  function sanitizeValue(value) {
68
120
  if (Array.isArray(value)) {
@@ -70,7 +122,7 @@ function sanitizeValue(value) {
70
122
  let removedCount = 0;
71
123
  const sanitizedItems = [];
72
124
  for (const item of value) {
73
- if (isEncryptedReasoningItem(item)) {
125
+ if (isReasoningInputItem(item)) {
74
126
  modified = true;
75
127
  removedCount++;
76
128
  continue;
@@ -110,10 +162,15 @@ function sanitizeValue(value) {
110
162
  }
111
163
  return { value: result, modified, removedCount };
112
164
  }
113
- function isEncryptedReasoningItem(value) {
114
- return isPlainObject(value) &&
115
- value.type === 'reasoning' &&
116
- typeof value.encrypted_content === 'string';
165
+ /**
166
+ * Any replayed reasoning item is deployment-bound state, not just the encrypted ones.
167
+ * Once `include: ["reasoning.encrypted_content"]` is stripped the upstream response
168
+ * carries reasoning items without `encrypted_content`; clients that persist and replay
169
+ * them (pi) then send a bare `rs_...` id, which `store: false` requests cannot resolve
170
+ * ("Item with id 'rs_...' not found"). Drop the whole item in both shapes.
171
+ */
172
+ function isReasoningInputItem(value) {
173
+ return isPlainObject(value) && value.type === 'reasoning';
117
174
  }
118
175
  function isPlainObject(value) {
119
176
  return typeof value === 'object' && value !== null && !Array.isArray(value);
@@ -1 +1 @@
1
- {"version":3,"file":"codex-encrypted-content-sanitizer.plugin.js","sourceRoot":"","sources":["../../../../../../src/providers/plugins/sso/proxy/plugins/codex-encrypted-content-sanitizer.plugin.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"codex-encrypted-content-sanitizer.plugin.js","sourceRoot":"","sources":["../../../../../../src/providers/plugins/sso/proxy/plugins/codex-encrypted-content-sanitizer.plugin.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Copilot Encrypted Content Sanitizer
3
+ * Priority: 16 (after generic request sanitizer, before header injection)
4
+ *
5
+ * GitHub Copilot CLI can replay Responses API reasoning items whose
6
+ * `encrypted_content` is deployment-bound. If LiteLLM/Azure rejects a replayed
7
+ * item before the response is streamed downstream, retry the same request once
8
+ * after stripping replayed reasoning state so the Copilot session can continue.
9
+ *
10
+ * Scope: codemie-copilot only. The Codex sanitizer intentionally keeps its
11
+ * original latch-only behavior in codex-encrypted-content-sanitizer.plugin.ts.
12
+ */
13
+ import { ProxyPlugin, PluginContext, ProxyInterceptor } from './types.js';
14
+ export declare class CopilotEncryptedContentSanitizerPlugin implements ProxyPlugin {
15
+ id: string;
16
+ name: string;
17
+ version: string;
18
+ priority: number;
19
+ createInterceptor(context: PluginContext): Promise<ProxyInterceptor>;
20
+ }
21
+ //# sourceMappingURL=copilot-encrypted-content-sanitizer.plugin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"copilot-encrypted-content-sanitizer.plugin.d.ts","sourceRoot":"","sources":["../../../../../../src/providers/plugins/sso/proxy/plugins/copilot-encrypted-content-sanitizer.plugin.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAGH,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,gBAAgB,EAAyB,MAAM,YAAY,CAAC;AAkBjG,qBAAa,sCAAuC,YAAW,WAAW;IACxE,EAAE,SAAwD;IAC1D,IAAI,SAAyC;IAC7C,OAAO,SAAW;IAClB,QAAQ,SAAM;IAER,iBAAiB,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,gBAAgB,CAAC;CAQ3E"}
@@ -0,0 +1,133 @@
1
+ /**
2
+ * Copilot Encrypted Content Sanitizer
3
+ * Priority: 16 (after generic request sanitizer, before header injection)
4
+ *
5
+ * GitHub Copilot CLI can replay Responses API reasoning items whose
6
+ * `encrypted_content` is deployment-bound. If LiteLLM/Azure rejects a replayed
7
+ * item before the response is streamed downstream, retry the same request once
8
+ * after stripping replayed reasoning state so the Copilot session can continue.
9
+ *
10
+ * Scope: codemie-copilot only. The Codex sanitizer intentionally keeps its
11
+ * original latch-only behavior in codex-encrypted-content-sanitizer.plugin.ts.
12
+ */
13
+ import { logger } from '../../../../../utils/logger.js';
14
+ const ALLOWED_AGENTS = ['codemie-copilot'];
15
+ const ENCRYPTED_CONTENT_INCLUDE = 'reasoning.encrypted_content';
16
+ const RESPONSES_PATH_SUFFIX = '/responses';
17
+ const UNUSABLE_REASONING_STATE_MARKERS = [
18
+ 'invalid_encrypted_content',
19
+ 'Items are not persisted when',
20
+ ];
21
+ export class CopilotEncryptedContentSanitizerPlugin {
22
+ id = '@codemie/proxy-copilot-encrypted-content-sanitizer';
23
+ name = 'Copilot Encrypted Content Sanitizer';
24
+ version = '1.0.0';
25
+ priority = 16;
26
+ async createInterceptor(context) {
27
+ const clientType = context.config.clientType;
28
+ if (!clientType || !ALLOWED_AGENTS.includes(clientType)) {
29
+ throw new Error(`Plugin disabled for agent: ${clientType}`);
30
+ }
31
+ return new CopilotEncryptedContentSanitizerInterceptor(clientType);
32
+ }
33
+ }
34
+ class CopilotEncryptedContentSanitizerInterceptor {
35
+ clientType;
36
+ name = 'copilot-encrypted-content-sanitizer';
37
+ constructor(clientType) {
38
+ this.clientType = clientType;
39
+ }
40
+ async onUpstreamResponse(context, response, tools) {
41
+ if (!this.isResponsesRequest(context) || (response.statusCode ?? 200) < 400) {
42
+ return response;
43
+ }
44
+ const responseBody = await tools.readBody(response);
45
+ const marker = UNUSABLE_REASONING_STATE_MARKERS.find(m => responseBody.includes(m));
46
+ if (!marker) {
47
+ return tools.fromBuffer(response, responseBody);
48
+ }
49
+ const sanitizedRequest = this.sanitizeRequestBody(context);
50
+ if (!sanitizedRequest) {
51
+ return tools.fromBuffer(response, responseBody);
52
+ }
53
+ logger.warn(`[${this.name}] Upstream rejected replayed reasoning state for ${this.clientType} ("${marker}"). ` +
54
+ `Retrying once without reasoning state: ${sanitizedRequest.removedCount} item(s) removed.`);
55
+ return tools.retry(sanitizedRequest.body);
56
+ }
57
+ isResponsesRequest(context) {
58
+ const path = context.url.split('?')[0].replace(/\/+$/, '');
59
+ return path.endsWith(RESPONSES_PATH_SUFFIX);
60
+ }
61
+ sanitizeRequestBody(context) {
62
+ if (!context.requestBody || !context.headers['content-type']?.includes('application/json')) {
63
+ return null;
64
+ }
65
+ try {
66
+ const body = JSON.parse(context.requestBody.toString('utf-8'));
67
+ const sanitized = sanitizeValue(body);
68
+ if (!sanitized.modified) {
69
+ return null;
70
+ }
71
+ const newBody = Buffer.from(JSON.stringify(sanitized.value), 'utf-8');
72
+ context.requestBody = newBody;
73
+ context.headers['content-length'] = String(newBody.length);
74
+ return { body: newBody, removedCount: sanitized.removedCount };
75
+ }
76
+ catch {
77
+ return null;
78
+ }
79
+ }
80
+ }
81
+ function sanitizeValue(value) {
82
+ if (Array.isArray(value)) {
83
+ let modified = false;
84
+ let removedCount = 0;
85
+ const sanitizedItems = [];
86
+ for (const item of value) {
87
+ if (isReasoningInputItem(item)) {
88
+ modified = true;
89
+ removedCount++;
90
+ continue;
91
+ }
92
+ const sanitized = sanitizeValue(item);
93
+ modified = modified || sanitized.modified;
94
+ removedCount += sanitized.removedCount;
95
+ sanitizedItems.push(sanitized.value);
96
+ }
97
+ return { value: sanitizedItems, modified, removedCount };
98
+ }
99
+ if (!isPlainObject(value)) {
100
+ return { value, modified: false, removedCount: 0 };
101
+ }
102
+ let modified = false;
103
+ let removedCount = 0;
104
+ const result = {};
105
+ for (const [key, childValue] of Object.entries(value)) {
106
+ if (key === 'encrypted_content') {
107
+ modified = true;
108
+ removedCount++;
109
+ continue;
110
+ }
111
+ if (key === 'include' && Array.isArray(childValue)) {
112
+ const filteredInclude = childValue.filter(item => item !== ENCRYPTED_CONTENT_INCLUDE);
113
+ if (filteredInclude.length !== childValue.length) {
114
+ modified = true;
115
+ removedCount += childValue.length - filteredInclude.length;
116
+ }
117
+ result[key] = filteredInclude;
118
+ continue;
119
+ }
120
+ const sanitized = sanitizeValue(childValue);
121
+ modified = modified || sanitized.modified;
122
+ removedCount += sanitized.removedCount;
123
+ result[key] = sanitized.value;
124
+ }
125
+ return { value: result, modified, removedCount };
126
+ }
127
+ function isReasoningInputItem(value) {
128
+ return isPlainObject(value) && value.type === 'reasoning';
129
+ }
130
+ function isPlainObject(value) {
131
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
132
+ }
133
+ //# sourceMappingURL=copilot-encrypted-content-sanitizer.plugin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"copilot-encrypted-content-sanitizer.plugin.js","sourceRoot":"","sources":["../../../../../../src/providers/plugins/sso/proxy/plugins/copilot-encrypted-content-sanitizer.plugin.ts"],"names":[],"mappings":"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"}
@@ -28,7 +28,7 @@ class HeaderInjectionInterceptor {
28
28
  context.headers['X-CodeMie-Session-ID'] = context.sessionId;
29
29
  // LiteLLM can use these headers for Responses API session affinity when
30
30
  // its router is configured with session-aware pre-call checks.
31
- if (this.context.config.clientType === 'codemie-codex') {
31
+ if (this.context.config.clientType === 'codemie-codex' || this.context.config.clientType === 'codemie-copilot') {
32
32
  context.headers['x-litellm-session-id'] = context.sessionId;
33
33
  }
34
34
  // Add CLI version header
@@ -1 +1 @@
1
- {"version":3,"file":"header-injection.plugin.js","sourceRoot":"","sources":["../../../../../../src/providers/plugins/sso/proxy/plugins/header-injection.plugin.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"header-injection.plugin.js","sourceRoot":"","sources":["../../../../../../src/providers/plugins/sso/proxy/plugins/header-injection.plugin.ts"],"names":[],"mappings":"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"}
@@ -14,6 +14,7 @@ import { RequestSanitizerPlugin } from './request-sanitizer.plugin.js';
14
14
  import { ClaudeRequestNormalizerPlugin } from './claude-request-normalizer.plugin.js';
15
15
  import { KimiRequestNormalizerPlugin } from './kimi-request-normalizer.plugin.js';
16
16
  import { CodexEncryptedContentSanitizerPlugin } from './codex-encrypted-content-sanitizer.plugin.js';
17
+ import { CopilotEncryptedContentSanitizerPlugin } from './copilot-encrypted-content-sanitizer.plugin.js';
17
18
  import { VsCodeRequestNormalizerPlugin } from './vscode-request-normalizer.plugin.js';
18
19
  import { LoggingPlugin } from './logging.plugin.js';
19
20
  /**
@@ -21,7 +22,7 @@ import { LoggingPlugin } from './logging.plugin.js';
21
22
  * Called at app startup
22
23
  */
23
24
  export declare function registerCorePlugins(): void;
24
- export { MCPAuthPlugin, EndpointBlockerPlugin, GatewayKeyPlugin, SSOAuthPlugin, JWTAuthPlugin, HeaderInjectionPlugin, RequestSanitizerPlugin, ClaudeRequestNormalizerPlugin, KimiRequestNormalizerPlugin, CodexEncryptedContentSanitizerPlugin, VsCodeRequestNormalizerPlugin, LoggingPlugin, };
25
+ export { MCPAuthPlugin, EndpointBlockerPlugin, GatewayKeyPlugin, SSOAuthPlugin, JWTAuthPlugin, HeaderInjectionPlugin, RequestSanitizerPlugin, ClaudeRequestNormalizerPlugin, KimiRequestNormalizerPlugin, CodexEncryptedContentSanitizerPlugin, CopilotEncryptedContentSanitizerPlugin, VsCodeRequestNormalizerPlugin, LoggingPlugin, };
25
26
  export { SSOSessionSyncPlugin } from './sso.session-sync.plugin.js';
26
27
  export { getPluginRegistry, resetPluginRegistry } from './registry.js';
27
28
  export * from './types.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../src/providers/plugins/sso/proxy/plugins/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,qBAAqB,EAAE,MAAM,8BAA8B,CAAC;AACrE,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,qBAAqB,EAAE,MAAM,8BAA8B,CAAC;AACrE,OAAO,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAC;AACvE,OAAO,EAAE,6BAA6B,EAAE,MAAM,uCAAuC,CAAC;AACtF,OAAO,EAAE,2BAA2B,EAAE,MAAM,qCAAqC,CAAC;AAClF,OAAO,EAAE,oCAAoC,EAAE,MAAM,+CAA+C,CAAC;AACrG,OAAO,EAAE,6BAA6B,EAAE,MAAM,uCAAuC,CAAC;AACtF,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAGpD;;;GAGG;AACH,wBAAgB,mBAAmB,IAAI,IAAI,CAiB1C;AAMD,OAAO,EACL,aAAa,EACb,qBAAqB,EACrB,gBAAgB,EAChB,aAAa,EACb,aAAa,EACb,qBAAqB,EACrB,sBAAsB,EACtB,6BAA6B,EAC7B,2BAA2B,EAC3B,oCAAoC,EACpC,6BAA6B,EAC7B,aAAa,GACd,CAAC;AACF,OAAO,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAC;AACpE,OAAO,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AACvE,cAAc,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../src/providers/plugins/sso/proxy/plugins/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,qBAAqB,EAAE,MAAM,8BAA8B,CAAC;AACrE,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,qBAAqB,EAAE,MAAM,8BAA8B,CAAC;AACrE,OAAO,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAC;AACvE,OAAO,EAAE,6BAA6B,EAAE,MAAM,uCAAuC,CAAC;AACtF,OAAO,EAAE,2BAA2B,EAAE,MAAM,qCAAqC,CAAC;AAClF,OAAO,EAAE,oCAAoC,EAAE,MAAM,+CAA+C,CAAC;AACrG,OAAO,EAAE,sCAAsC,EAAE,MAAM,iDAAiD,CAAC;AACzG,OAAO,EAAE,6BAA6B,EAAE,MAAM,uCAAuC,CAAC;AACtF,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAGpD;;;GAGG;AACH,wBAAgB,mBAAmB,IAAI,IAAI,CAkB1C;AAMD,OAAO,EACL,aAAa,EACb,qBAAqB,EACrB,gBAAgB,EAChB,aAAa,EACb,aAAa,EACb,qBAAqB,EACrB,sBAAsB,EACtB,6BAA6B,EAC7B,2BAA2B,EAC3B,oCAAoC,EACpC,sCAAsC,EACtC,6BAA6B,EAC7B,aAAa,GACd,CAAC;AACF,OAAO,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAC;AACpE,OAAO,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AACvE,cAAc,YAAY,CAAC"}
@@ -15,6 +15,7 @@ import { RequestSanitizerPlugin } from './request-sanitizer.plugin.js';
15
15
  import { ClaudeRequestNormalizerPlugin } from './claude-request-normalizer.plugin.js';
16
16
  import { KimiRequestNormalizerPlugin } from './kimi-request-normalizer.plugin.js';
17
17
  import { CodexEncryptedContentSanitizerPlugin } from './codex-encrypted-content-sanitizer.plugin.js';
18
+ import { CopilotEncryptedContentSanitizerPlugin } from './copilot-encrypted-content-sanitizer.plugin.js';
18
19
  import { VsCodeRequestNormalizerPlugin } from './vscode-request-normalizer.plugin.js';
19
20
  import { LoggingPlugin } from './logging.plugin.js';
20
21
  import { SSOSessionSyncPlugin } from './sso.session-sync.plugin.js';
@@ -33,7 +34,8 @@ export function registerCorePlugins() {
33
34
  registry.register(new ClaudeRequestNormalizerPlugin()); // Priority 14 - normalizes thinking params for claude models
34
35
  registry.register(new KimiRequestNormalizerPlugin()); // Priority 14 - caps Kimi output token requests for upstream limits
35
36
  registry.register(new RequestSanitizerPlugin()); // Priority 15 - strips unsupported reasoning params
36
- registry.register(new CodexEncryptedContentSanitizerPlugin()); // Priority 16 - strips deployment-bound encrypted Responses reasoning state
37
+ registry.register(new CodexEncryptedContentSanitizerPlugin()); // Priority 16 - forwards Responses reasoning state; strips it only after upstream rejects a replay
38
+ registry.register(new CopilotEncryptedContentSanitizerPlugin()); // Priority 16 - retries Copilot once after encrypted reasoning replay rejection
37
39
  registry.register(new VsCodeRequestNormalizerPlugin()); // Priority 17 - constrains VS Code user identifiers
38
40
  registry.register(new HeaderInjectionPlugin());
39
41
  registry.register(new LoggingPlugin()); // Always enabled - logs to log files at INFO level
@@ -42,7 +44,7 @@ export function registerCorePlugins() {
42
44
  // Auto-register on import
43
45
  registerCorePlugins();
44
46
  // Re-export for convenience
45
- export { MCPAuthPlugin, EndpointBlockerPlugin, GatewayKeyPlugin, SSOAuthPlugin, JWTAuthPlugin, HeaderInjectionPlugin, RequestSanitizerPlugin, ClaudeRequestNormalizerPlugin, KimiRequestNormalizerPlugin, CodexEncryptedContentSanitizerPlugin, VsCodeRequestNormalizerPlugin, LoggingPlugin, };
47
+ export { MCPAuthPlugin, EndpointBlockerPlugin, GatewayKeyPlugin, SSOAuthPlugin, JWTAuthPlugin, HeaderInjectionPlugin, RequestSanitizerPlugin, ClaudeRequestNormalizerPlugin, KimiRequestNormalizerPlugin, CodexEncryptedContentSanitizerPlugin, CopilotEncryptedContentSanitizerPlugin, VsCodeRequestNormalizerPlugin, LoggingPlugin, };
46
48
  export { SSOSessionSyncPlugin } from './sso.session-sync.plugin.js';
47
49
  export { getPluginRegistry, resetPluginRegistry } from './registry.js';
48
50
  export * from './types.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../../src/providers/plugins/sso/proxy/plugins/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,qBAAqB,EAAE,MAAM,8BAA8B,CAAC;AACrE,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,qBAAqB,EAAE,MAAM,8BAA8B,CAAC;AACrE,OAAO,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAC;AACvE,OAAO,EAAE,6BAA6B,EAAE,MAAM,uCAAuC,CAAC;AACtF,OAAO,EAAE,2BAA2B,EAAE,MAAM,qCAAqC,CAAC;AAClF,OAAO,EAAE,oCAAoC,EAAE,MAAM,+CAA+C,CAAC;AACrG,OAAO,EAAE,6BAA6B,EAAE,MAAM,uCAAuC,CAAC;AACtF,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAC;AAEpE;;;GAGG;AACH,MAAM,UAAU,mBAAmB;IACjC,MAAM,QAAQ,GAAG,iBAAiB,EAAE,CAAC;IAErC,8DAA8D;IAC9D,QAAQ,CAAC,QAAQ,CAAC,IAAI,aAAa,EAAE,CAAC,CAAC,CAAC,sCAAsC;IAC9E,QAAQ,CAAC,QAAQ,CAAC,IAAI,qBAAqB,EAAE,CAAC,CAAC,CAAC,+CAA+C;IAC/F,QAAQ,CAAC,QAAQ,CAAC,IAAI,gBAAgB,EAAE,CAAC,CAAC,CAAC,2EAA2E;IACtH,QAAQ,CAAC,QAAQ,CAAC,IAAI,aAAa,EAAE,CAAC,CAAC;IACvC,QAAQ,CAAC,QAAQ,CAAC,IAAI,aAAa,EAAE,CAAC,CAAC;IACvC,QAAQ,CAAC,QAAQ,CAAC,IAAI,6BAA6B,EAAE,CAAC,CAAC,CAAC,6DAA6D;IACrH,QAAQ,CAAC,QAAQ,CAAC,IAAI,2BAA2B,EAAE,CAAC,CAAC,CAAC,oEAAoE;IAC1H,QAAQ,CAAC,QAAQ,CAAC,IAAI,sBAAsB,EAAE,CAAC,CAAC,CAAC,oDAAoD;IACrG,QAAQ,CAAC,QAAQ,CAAC,IAAI,oCAAoC,EAAE,CAAC,CAAC,CAAC,4EAA4E;IAC3I,QAAQ,CAAC,QAAQ,CAAC,IAAI,6BAA6B,EAAE,CAAC,CAAC,CAAC,oDAAoD;IAC5G,QAAQ,CAAC,QAAQ,CAAC,IAAI,qBAAqB,EAAE,CAAC,CAAC;IAC/C,QAAQ,CAAC,QAAQ,CAAC,IAAI,aAAa,EAAE,CAAC,CAAC,CAAC,mDAAmD;IAC3F,QAAQ,CAAC,QAAQ,CAAC,IAAI,oBAAoB,EAAE,CAAC,CAAC,CAAC,wDAAwD;AACzG,CAAC;AAED,0BAA0B;AAC1B,mBAAmB,EAAE,CAAC;AAEtB,4BAA4B;AAC5B,OAAO,EACL,aAAa,EACb,qBAAqB,EACrB,gBAAgB,EAChB,aAAa,EACb,aAAa,EACb,qBAAqB,EACrB,sBAAsB,EACtB,6BAA6B,EAC7B,2BAA2B,EAC3B,oCAAoC,EACpC,6BAA6B,EAC7B,aAAa,GACd,CAAC;AACF,OAAO,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAC;AACpE,OAAO,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AACvE,cAAc,YAAY,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../../src/providers/plugins/sso/proxy/plugins/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,qBAAqB,EAAE,MAAM,8BAA8B,CAAC;AACrE,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,qBAAqB,EAAE,MAAM,8BAA8B,CAAC;AACrE,OAAO,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAC;AACvE,OAAO,EAAE,6BAA6B,EAAE,MAAM,uCAAuC,CAAC;AACtF,OAAO,EAAE,2BAA2B,EAAE,MAAM,qCAAqC,CAAC;AAClF,OAAO,EAAE,oCAAoC,EAAE,MAAM,+CAA+C,CAAC;AACrG,OAAO,EAAE,sCAAsC,EAAE,MAAM,iDAAiD,CAAC;AACzG,OAAO,EAAE,6BAA6B,EAAE,MAAM,uCAAuC,CAAC;AACtF,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAC;AAEpE;;;GAGG;AACH,MAAM,UAAU,mBAAmB;IACjC,MAAM,QAAQ,GAAG,iBAAiB,EAAE,CAAC;IAErC,8DAA8D;IAC9D,QAAQ,CAAC,QAAQ,CAAC,IAAI,aAAa,EAAE,CAAC,CAAC,CAAC,sCAAsC;IAC9E,QAAQ,CAAC,QAAQ,CAAC,IAAI,qBAAqB,EAAE,CAAC,CAAC,CAAC,+CAA+C;IAC/F,QAAQ,CAAC,QAAQ,CAAC,IAAI,gBAAgB,EAAE,CAAC,CAAC,CAAC,2EAA2E;IACtH,QAAQ,CAAC,QAAQ,CAAC,IAAI,aAAa,EAAE,CAAC,CAAC;IACvC,QAAQ,CAAC,QAAQ,CAAC,IAAI,aAAa,EAAE,CAAC,CAAC;IACvC,QAAQ,CAAC,QAAQ,CAAC,IAAI,6BAA6B,EAAE,CAAC,CAAC,CAAC,6DAA6D;IACrH,QAAQ,CAAC,QAAQ,CAAC,IAAI,2BAA2B,EAAE,CAAC,CAAC,CAAC,oEAAoE;IAC1H,QAAQ,CAAC,QAAQ,CAAC,IAAI,sBAAsB,EAAE,CAAC,CAAC,CAAC,oDAAoD;IACrG,QAAQ,CAAC,QAAQ,CAAC,IAAI,oCAAoC,EAAE,CAAC,CAAC,CAAC,mGAAmG;IAClK,QAAQ,CAAC,QAAQ,CAAC,IAAI,sCAAsC,EAAE,CAAC,CAAC,CAAC,gFAAgF;IACjJ,QAAQ,CAAC,QAAQ,CAAC,IAAI,6BAA6B,EAAE,CAAC,CAAC,CAAC,oDAAoD;IAC5G,QAAQ,CAAC,QAAQ,CAAC,IAAI,qBAAqB,EAAE,CAAC,CAAC;IAC/C,QAAQ,CAAC,QAAQ,CAAC,IAAI,aAAa,EAAE,CAAC,CAAC,CAAC,mDAAmD;IAC3F,QAAQ,CAAC,QAAQ,CAAC,IAAI,oBAAoB,EAAE,CAAC,CAAC,CAAC,wDAAwD;AACzG,CAAC;AAED,0BAA0B;AAC1B,mBAAmB,EAAE,CAAC;AAEtB,4BAA4B;AAC5B,OAAO,EACL,aAAa,EACb,qBAAqB,EACrB,gBAAgB,EAChB,aAAa,EACb,aAAa,EACb,qBAAqB,EACrB,sBAAsB,EACtB,6BAA6B,EAC7B,2BAA2B,EAC3B,oCAAoC,EACpC,sCAAsC,EACtC,6BAA6B,EAC7B,aAAa,GACd,CAAC;AACF,OAAO,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAC;AACpE,OAAO,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AACvE,cAAc,YAAY,CAAC"}
@@ -65,6 +65,12 @@ export interface ProxyInterceptor {
65
65
  onRequest?(context: ProxyContext): Promise<void>;
66
66
  /** Called after response headers received (BEFORE body streaming) */
67
67
  onResponseHeaders?(context: ProxyContext, headers: IncomingHttpHeaders): Promise<void>;
68
+ /**
69
+ * Called after the upstream response is received but before headers/body are
70
+ * streamed downstream. Interceptors may return the original response or a
71
+ * replacement response (for example, after a sanitized one-shot retry).
72
+ */
73
+ onUpstreamResponse?(context: ProxyContext, response: IncomingMessage, tools: UpstreamResponseTools): Promise<IncomingMessage>;
68
74
  /** Called during streaming (optional, for transform/inspection) */
69
75
  onResponseChunk?(context: ProxyContext, chunk: Buffer): Promise<Buffer | null>;
70
76
  /** Called after response fully streamed */
@@ -88,6 +94,11 @@ export interface ProxyInterceptor {
88
94
  */
89
95
  handleRequest?(context: ProxyContext, req: IncomingMessage, res: ServerResponse, httpClient: ProxyHTTPClient): Promise<boolean>;
90
96
  }
97
+ export interface UpstreamResponseTools {
98
+ readBody(response: IncomingMessage): Promise<Buffer>;
99
+ retry(requestBody: Buffer): Promise<IncomingMessage>;
100
+ fromBuffer(response: IncomingMessage, body: Buffer): IncomingMessage;
101
+ }
91
102
  /**
92
103
  * Response metadata (after streaming)
93
104
  */
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../../../src/providers/plugins/sso/proxy/plugins/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../../../src/providers/plugins/sso/proxy/plugins/types.ts"],"names":[],"mappings":"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"}
@@ -82,6 +82,8 @@ export declare class CodeMieProxy {
82
82
  * For onRequest hooks: stop execution if any plugin blocks the request
83
83
  */
84
84
  private runHook;
85
+ private runUpstreamResponseHooks;
86
+ private createBufferedResponse;
85
87
  /**
86
88
  * Handle errors with proper status codes and structure
87
89
  */
@@ -1 +1 @@
1
- {"version":3,"file":"sso.proxy.d.ts","sourceRoot":"","sources":["../../../../../src/providers/plugins/sso/proxy/sso.proxy.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAUH,OAAO,EAAE,WAAW,EAAgB,MAAM,kBAAkB,CAAC;AAI7D,OAAO,oBAAoB,CAAC;AAE5B;;;GAGG;AACH,qBAAa,YAAY;IAOX,OAAO,CAAC,MAAM;IAN1B,OAAO,CAAC,MAAM,CAAuB;IACrC,OAAO,CAAC,UAAU,CAAkB;IACpC,OAAO,CAAC,YAAY,CAA0B;IAC9C,OAAO,CAAC,UAAU,CAAa;IAC/B,OAAO,CAAC,SAAS,CAAc;gBAEX,MAAM,EAAE,WAAW;IAQvC;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC;IAuIrD;;OAEG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAyB3B;;;;;;;;;;;;OAYG;YACW,aAAa;IAsI3B;;OAEG;YACW,YAAY;IA0B1B;;OAEG;IACH,OAAO,CAAC,cAAc;IAatB;;;OAGG;YACW,QAAQ;IAiBtB;;OAEG;YACW,cAAc;IAkG5B;;;OAGG;YACW,OAAO;IAqBrB;;OAEG;YACW,WAAW;IAsDzB;;OAEG;IACH,OAAO,CAAC,iBAAiB;IA6BzB;;;;OAIG;IACH,OAAO,CAAC,uBAAuB;IAoB/B;;OAEG;YACW,iBAAiB;IAuB/B;;OAEG;YACW,gBAAgB;CAU/B"}
1
+ {"version":3,"file":"sso.proxy.d.ts","sourceRoot":"","sources":["../../../../../src/providers/plugins/sso/proxy/sso.proxy.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAWH,OAAO,EAAE,WAAW,EAAgB,MAAM,kBAAkB,CAAC;AAI7D,OAAO,oBAAoB,CAAC;AAE5B;;;GAGG;AACH,qBAAa,YAAY;IAOX,OAAO,CAAC,MAAM;IAN1B,OAAO,CAAC,MAAM,CAAuB;IACrC,OAAO,CAAC,UAAU,CAAkB;IACpC,OAAO,CAAC,YAAY,CAA0B;IAC9C,OAAO,CAAC,UAAU,CAAa;IAC/B,OAAO,CAAC,SAAS,CAAc;gBAEX,MAAM,EAAE,WAAW;IAQvC;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC;IAuIrD;;OAEG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAyB3B;;;;;;;;;;;;OAYG;YACW,aAAa;IAwI3B;;OAEG;YACW,YAAY;IA0B1B;;OAEG;IACH,OAAO,CAAC,cAAc;IAatB;;;OAGG;YACW,QAAQ;IAiBtB;;OAEG;YACW,cAAc;IAkG5B;;;OAGG;YACW,OAAO;YAqBP,wBAAwB;IAiCtC,OAAO,CAAC,sBAAsB;IAa9B;;OAEG;YACW,WAAW;IAsDzB;;OAEG;IACH,OAAO,CAAC,iBAAiB;IA6BzB;;;;OAIG;IACH,OAAO,CAAC,uBAAuB;IAoB/B;;OAEG;YACW,iBAAiB;IAuB/B;;OAEG;YACW,gBAAgB;CAU/B"}
@@ -24,6 +24,7 @@
24
24
  import { createServer } from 'http';
25
25
  import { randomUUID } from 'crypto';
26
26
  import { URL } from 'url';
27
+ import { Readable } from 'stream';
27
28
  import { ProviderRegistry } from '../../../core/registry.js';
28
29
  import { AuthMethod } from '../../../core/types.js';
29
30
  import { logger } from '../../../../utils/logger.js';
@@ -267,12 +268,13 @@ export class CodeMieProxy {
267
268
  gatewayKeyValidated: Boolean(context.metadata.gatewayKeyValidated),
268
269
  });
269
270
  logger.debug(`[proxy] Forwarding request to upstream for ${context.requestId}`);
270
- const upstreamResponse = await this.httpClient.forward(targetUrl, {
271
+ let upstreamResponse = await this.httpClient.forward(targetUrl, {
271
272
  method: req.method,
272
273
  headers: context.headers,
273
274
  body: context.requestBody || undefined
274
275
  });
275
276
  logger.debug(`[proxy] Received upstream response object for ${context.requestId}`);
277
+ upstreamResponse = await this.runUpstreamResponseHooks(context, upstreamResponse, targetUrl, req.method);
276
278
  // 4. Run onResponseHeaders hooks (BEFORE streaming)
277
279
  await this.runHook('onResponseHeaders', interceptor => interceptor.onResponseHeaders?.(context, upstreamResponse.headers));
278
280
  // 5. Stream response to client
@@ -460,6 +462,40 @@ export class CodeMieProxy {
460
462
  }
461
463
  }
462
464
  }
465
+ async runUpstreamResponseHooks(context, upstreamResponse, targetUrl, method) {
466
+ let response = upstreamResponse;
467
+ const tools = {
468
+ readBody: (incoming) => this.httpClient.readResponseBody(incoming),
469
+ retry: (requestBody) => this.httpClient.forward(targetUrl, {
470
+ method,
471
+ headers: context.headers,
472
+ body: requestBody,
473
+ }),
474
+ fromBuffer: (incoming, body) => this.createBufferedResponse(incoming, body),
475
+ };
476
+ for (const interceptor of this.interceptors) {
477
+ if (!interceptor.onUpstreamResponse) {
478
+ continue;
479
+ }
480
+ try {
481
+ response = await interceptor.onUpstreamResponse(context, response, tools);
482
+ }
483
+ catch (error) {
484
+ logger.error(`[CodeMieProxy] Upstream response hook error in ${interceptor.name}:`, error);
485
+ }
486
+ }
487
+ return response;
488
+ }
489
+ createBufferedResponse(source, body) {
490
+ const readable = Readable.from(body);
491
+ readable.statusCode = source.statusCode;
492
+ readable.statusMessage = source.statusMessage;
493
+ readable.headers = {
494
+ ...source.headers,
495
+ 'content-length': String(body.length),
496
+ };
497
+ return readable;
498
+ }
463
499
  /**
464
500
  * Handle errors with proper status codes and structure
465
501
  */