@codemieai/code 0.12.0 → 0.13.1
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/README.md +146 -57
- package/bin/codemie-copilot.js +224 -0
- package/bin/codemie-pi.js +18 -0
- package/dist/agents/core/AgentCLI.d.ts.map +1 -1
- package/dist/agents/core/AgentCLI.js +16 -10
- package/dist/agents/core/AgentCLI.js.map +1 -1
- package/dist/agents/core/BaseAgentAdapter.d.ts.map +1 -1
- package/dist/agents/core/BaseAgentAdapter.js +43 -19
- package/dist/agents/core/BaseAgentAdapter.js.map +1 -1
- package/dist/agents/core/agent-aliases.d.ts +17 -0
- package/dist/agents/core/agent-aliases.d.ts.map +1 -0
- package/dist/agents/core/agent-aliases.js +41 -0
- package/dist/agents/core/agent-aliases.js.map +1 -0
- package/dist/agents/core/session/session-origin-audit.d.ts +13 -0
- package/dist/agents/core/session/session-origin-audit.d.ts.map +1 -1
- package/dist/agents/core/session/session-origin-audit.js +34 -0
- package/dist/agents/core/session/session-origin-audit.js.map +1 -1
- package/dist/agents/core/session/stale-session-reconciliation.d.ts +42 -0
- package/dist/agents/core/session/stale-session-reconciliation.d.ts.map +1 -0
- package/dist/agents/core/session/stale-session-reconciliation.js +141 -0
- package/dist/agents/core/session/stale-session-reconciliation.js.map +1 -0
- package/dist/agents/core/session/types.d.ts +19 -0
- package/dist/agents/core/session/types.d.ts.map +1 -1
- package/dist/agents/core/session/types.js +17 -1
- package/dist/agents/core/session/types.js.map +1 -1
- package/dist/agents/core/types.d.ts +1 -0
- package/dist/agents/core/types.d.ts.map +1 -1
- package/dist/agents/plugins/codex/codex.reconciliation.d.ts +15 -35
- package/dist/agents/plugins/codex/codex.reconciliation.d.ts.map +1 -1
- package/dist/agents/plugins/codex/codex.reconciliation.js +8 -139
- package/dist/agents/plugins/codex/codex.reconciliation.js.map +1 -1
- package/dist/agents/plugins/copilot-cli/copilot-cli.constants.d.ts +4 -0
- package/dist/agents/plugins/copilot-cli/copilot-cli.constants.d.ts.map +1 -1
- package/dist/agents/plugins/copilot-cli/copilot-cli.constants.js +4 -0
- package/dist/agents/plugins/copilot-cli/copilot-cli.constants.js.map +1 -1
- package/dist/agents/plugins/copilot-cli/copilot-cli.models.d.ts +8 -0
- package/dist/agents/plugins/copilot-cli/copilot-cli.models.d.ts.map +1 -0
- package/dist/agents/plugins/copilot-cli/copilot-cli.models.js +195 -0
- package/dist/agents/plugins/copilot-cli/copilot-cli.models.js.map +1 -0
- package/dist/agents/plugins/copilot-cli/copilot-cli.plugin.d.ts +4 -20
- package/dist/agents/plugins/copilot-cli/copilot-cli.plugin.d.ts.map +1 -1
- package/dist/agents/plugins/copilot-cli/copilot-cli.plugin.js +237 -38
- package/dist/agents/plugins/copilot-cli/copilot-cli.plugin.js.map +1 -1
- package/dist/agents/plugins/copilot-cli/copilot-cli.session.d.ts.map +1 -1
- package/dist/agents/plugins/copilot-cli/copilot-cli.session.js +14 -2
- package/dist/agents/plugins/copilot-cli/copilot-cli.session.js.map +1 -1
- package/dist/agents/plugins/copilot-cli/index.d.ts +2 -1
- package/dist/agents/plugins/copilot-cli/index.d.ts.map +1 -1
- package/dist/agents/plugins/copilot-cli/index.js +2 -1
- package/dist/agents/plugins/copilot-cli/index.js.map +1 -1
- package/dist/agents/plugins/copilot-cli/session/processors/copilot-cli.conversations-processor.d.ts +6 -3
- package/dist/agents/plugins/copilot-cli/session/processors/copilot-cli.conversations-processor.d.ts.map +1 -1
- package/dist/agents/plugins/copilot-cli/session/processors/copilot-cli.conversations-processor.js +298 -5
- package/dist/agents/plugins/copilot-cli/session/processors/copilot-cli.conversations-processor.js.map +1 -1
- package/dist/agents/plugins/pi/__tests__/home-redirect.d.ts +12 -0
- package/dist/agents/plugins/pi/__tests__/home-redirect.d.ts.map +1 -0
- package/dist/agents/plugins/pi/__tests__/home-redirect.js +27 -0
- package/dist/agents/plugins/pi/__tests__/home-redirect.js.map +1 -0
- package/dist/agents/plugins/pi/extension/README.md +68 -0
- package/dist/agents/plugins/pi/extension/index.js +161 -0
- package/dist/agents/plugins/pi/extension/package.json +8 -0
- package/dist/agents/plugins/pi/index.d.ts +3 -0
- package/dist/agents/plugins/pi/index.d.ts.map +1 -0
- package/dist/agents/plugins/pi/index.js +3 -0
- package/dist/agents/plugins/pi/index.js.map +1 -0
- package/dist/agents/plugins/pi/pi.extension.d.ts +60 -0
- package/dist/agents/plugins/pi/pi.extension.d.ts.map +1 -0
- package/dist/agents/plugins/pi/pi.extension.js +201 -0
- package/dist/agents/plugins/pi/pi.extension.js.map +1 -0
- package/dist/agents/plugins/pi/pi.incremental-sync.d.ts +63 -0
- package/dist/agents/plugins/pi/pi.incremental-sync.d.ts.map +1 -0
- package/dist/agents/plugins/pi/pi.incremental-sync.js +266 -0
- package/dist/agents/plugins/pi/pi.incremental-sync.js.map +1 -0
- package/dist/agents/plugins/pi/pi.models.d.ts +20 -0
- package/dist/agents/plugins/pi/pi.models.d.ts.map +1 -0
- package/dist/agents/plugins/pi/pi.models.js +201 -0
- package/dist/agents/plugins/pi/pi.models.js.map +1 -0
- package/dist/agents/plugins/pi/pi.packages.d.ts +11 -0
- package/dist/agents/plugins/pi/pi.packages.d.ts.map +1 -0
- package/dist/agents/plugins/pi/pi.packages.js +35 -0
- package/dist/agents/plugins/pi/pi.packages.js.map +1 -0
- package/dist/agents/plugins/pi/pi.paths.d.ts +37 -0
- package/dist/agents/plugins/pi/pi.paths.d.ts.map +1 -0
- package/dist/agents/plugins/pi/pi.paths.js +146 -0
- package/dist/agents/plugins/pi/pi.paths.js.map +1 -0
- package/dist/agents/plugins/pi/pi.plugin.d.ts +30 -0
- package/dist/agents/plugins/pi/pi.plugin.d.ts.map +1 -0
- package/dist/agents/plugins/pi/pi.plugin.js +453 -0
- package/dist/agents/plugins/pi/pi.plugin.js.map +1 -0
- package/dist/agents/plugins/pi/pi.session.d.ts +114 -0
- package/dist/agents/plugins/pi/pi.session.d.ts.map +1 -0
- package/dist/agents/plugins/pi/pi.session.js +388 -0
- package/dist/agents/plugins/pi/pi.session.js.map +1 -0
- package/dist/agents/plugins/pi/pi.setup.d.ts +2 -0
- package/dist/agents/plugins/pi/pi.setup.d.ts.map +1 -0
- package/dist/agents/plugins/pi/pi.setup.js +33 -0
- package/dist/agents/plugins/pi/pi.setup.js.map +1 -0
- package/dist/agents/plugins/pi/pi.types.d.ts +143 -0
- package/dist/agents/plugins/pi/pi.types.d.ts.map +1 -0
- package/dist/agents/plugins/pi/pi.types.js +74 -0
- package/dist/agents/plugins/pi/pi.types.js.map +1 -0
- package/dist/agents/plugins/pi/session/pi-file-operations.d.ts +17 -0
- package/dist/agents/plugins/pi/session/pi-file-operations.d.ts.map +1 -0
- package/dist/agents/plugins/pi/session/pi-file-operations.js +98 -0
- package/dist/agents/plugins/pi/session/pi-file-operations.js.map +1 -0
- package/dist/agents/plugins/pi/session/pi-named-invocations.d.ts +52 -0
- package/dist/agents/plugins/pi/session/pi-named-invocations.d.ts.map +1 -0
- package/dist/agents/plugins/pi/session/pi-named-invocations.js +189 -0
- package/dist/agents/plugins/pi/session/pi-named-invocations.js.map +1 -0
- package/dist/agents/plugins/pi/session/pi-user-prompt.d.ts +14 -0
- package/dist/agents/plugins/pi/session/pi-user-prompt.d.ts.map +1 -0
- package/dist/agents/plugins/pi/session/pi-user-prompt.js +51 -0
- package/dist/agents/plugins/pi/session/pi-user-prompt.js.map +1 -0
- package/dist/agents/plugins/pi/session/processors/pi.conversations-processor.d.ts +52 -0
- package/dist/agents/plugins/pi/session/processors/pi.conversations-processor.d.ts.map +1 -0
- package/dist/agents/plugins/pi/session/processors/pi.conversations-processor.js +716 -0
- package/dist/agents/plugins/pi/session/processors/pi.conversations-processor.js.map +1 -0
- package/dist/agents/plugins/pi/session/processors/pi.metrics-processor.d.ts +104 -0
- package/dist/agents/plugins/pi/session/processors/pi.metrics-processor.d.ts.map +1 -0
- package/dist/agents/plugins/pi/session/processors/pi.metrics-processor.js +595 -0
- package/dist/agents/plugins/pi/session/processors/pi.metrics-processor.js.map +1 -0
- package/dist/agents/registry.d.ts.map +1 -1
- package/dist/agents/registry.js +2 -2
- package/dist/agents/registry.js.map +1 -1
- package/dist/cli/commands/analytics/agent-labels.d.ts.map +1 -1
- package/dist/cli/commands/analytics/agent-labels.js +1 -0
- package/dist/cli/commands/analytics/agent-labels.js.map +1 -1
- package/dist/cli/commands/analytics/cost/usage-readers.d.ts +24 -0
- package/dist/cli/commands/analytics/cost/usage-readers.d.ts.map +1 -1
- package/dist/cli/commands/analytics/cost/usage-readers.js +199 -54
- package/dist/cli/commands/analytics/cost/usage-readers.js.map +1 -1
- package/dist/cli/commands/analytics/index.js +1 -0
- package/dist/cli/commands/analytics/index.js.map +1 -1
- package/dist/cli/commands/analytics/native-loader.d.ts +21 -4
- package/dist/cli/commands/analytics/native-loader.d.ts.map +1 -1
- package/dist/cli/commands/analytics/native-loader.js +250 -96
- package/dist/cli/commands/analytics/native-loader.js.map +1 -1
- package/dist/cli/commands/analytics/report/client/app.js +47 -3
- package/dist/cli/commands/analytics/report/payload-builder.d.ts.map +1 -1
- package/dist/cli/commands/analytics/report/payload-builder.js +25 -2
- package/dist/cli/commands/analytics/report/payload-builder.js.map +1 -1
- package/dist/cli/commands/analytics/report/types.d.ts +1 -0
- package/dist/cli/commands/analytics/report/types.d.ts.map +1 -1
- package/dist/cli/commands/hook.d.ts.map +1 -1
- package/dist/cli/commands/hook.js +71 -29
- package/dist/cli/commands/hook.js.map +1 -1
- package/dist/cli/commands/install.d.ts.map +1 -1
- package/dist/cli/commands/install.js +7 -5
- package/dist/cli/commands/install.js.map +1 -1
- package/dist/cli/commands/list.d.ts.map +1 -1
- package/dist/cli/commands/list.js +3 -1
- package/dist/cli/commands/list.js.map +1 -1
- package/dist/cli/commands/proxy/connectors/desktop.d.ts +94 -4
- package/dist/cli/commands/proxy/connectors/desktop.d.ts.map +1 -1
- package/dist/cli/commands/proxy/connectors/desktop.js +244 -17
- package/dist/cli/commands/proxy/connectors/desktop.js.map +1 -1
- package/dist/cli/commands/proxy/connectors/managed-mcp-remote.d.ts +25 -0
- package/dist/cli/commands/proxy/connectors/managed-mcp-remote.d.ts.map +1 -1
- package/dist/cli/commands/proxy/connectors/managed-mcp-remote.js +59 -1
- package/dist/cli/commands/proxy/connectors/managed-mcp-remote.js.map +1 -1
- package/dist/cli/commands/proxy/index.d.ts.map +1 -1
- package/dist/cli/commands/proxy/index.js +10 -1
- package/dist/cli/commands/proxy/index.js.map +1 -1
- package/dist/cli/commands/uninstall.d.ts.map +1 -1
- package/dist/cli/commands/uninstall.js +5 -3
- package/dist/cli/commands/uninstall.js.map +1 -1
- package/dist/cli/commands/update.d.ts.map +1 -1
- package/dist/cli/commands/update.js +5 -3
- package/dist/cli/commands/update.js.map +1 -1
- package/dist/cli/first-time.d.ts.map +1 -1
- package/dist/cli/first-time.js +7 -6
- package/dist/cli/first-time.js.map +1 -1
- package/dist/providers/core/auth-validation.d.ts +7 -2
- package/dist/providers/core/auth-validation.d.ts.map +1 -1
- package/dist/providers/core/auth-validation.js +11 -5
- package/dist/providers/core/auth-validation.js.map +1 -1
- package/dist/providers/plugins/sso/proxy/plugins/claude-request-normalizer.plugin.d.ts +8 -3
- package/dist/providers/plugins/sso/proxy/plugins/claude-request-normalizer.plugin.d.ts.map +1 -1
- package/dist/providers/plugins/sso/proxy/plugins/claude-request-normalizer.plugin.js +46 -11
- package/dist/providers/plugins/sso/proxy/plugins/claude-request-normalizer.plugin.js.map +1 -1
- package/dist/providers/plugins/sso/proxy/plugins/codex-encrypted-content-sanitizer.plugin.d.ts +23 -13
- package/dist/providers/plugins/sso/proxy/plugins/codex-encrypted-content-sanitizer.plugin.d.ts.map +1 -1
- package/dist/providers/plugins/sso/proxy/plugins/codex-encrypted-content-sanitizer.plugin.js +75 -18
- package/dist/providers/plugins/sso/proxy/plugins/codex-encrypted-content-sanitizer.plugin.js.map +1 -1
- package/dist/providers/plugins/sso/proxy/plugins/copilot-encrypted-content-sanitizer.plugin.d.ts +21 -0
- package/dist/providers/plugins/sso/proxy/plugins/copilot-encrypted-content-sanitizer.plugin.d.ts.map +1 -0
- package/dist/providers/plugins/sso/proxy/plugins/copilot-encrypted-content-sanitizer.plugin.js +133 -0
- package/dist/providers/plugins/sso/proxy/plugins/copilot-encrypted-content-sanitizer.plugin.js.map +1 -0
- package/dist/providers/plugins/sso/proxy/plugins/header-injection.plugin.js +1 -1
- package/dist/providers/plugins/sso/proxy/plugins/header-injection.plugin.js.map +1 -1
- package/dist/providers/plugins/sso/proxy/plugins/index.d.ts +2 -1
- package/dist/providers/plugins/sso/proxy/plugins/index.d.ts.map +1 -1
- package/dist/providers/plugins/sso/proxy/plugins/index.js +4 -2
- package/dist/providers/plugins/sso/proxy/plugins/index.js.map +1 -1
- package/dist/providers/plugins/sso/proxy/plugins/types.d.ts +11 -0
- package/dist/providers/plugins/sso/proxy/plugins/types.d.ts.map +1 -1
- package/dist/providers/plugins/sso/proxy/sso.proxy.d.ts +2 -0
- package/dist/providers/plugins/sso/proxy/sso.proxy.d.ts.map +1 -1
- package/dist/providers/plugins/sso/proxy/sso.proxy.js +37 -1
- package/dist/providers/plugins/sso/proxy/sso.proxy.js.map +1 -1
- package/dist/providers/plugins/sso/session/SessionSyncer.d.ts.map +1 -1
- package/dist/providers/plugins/sso/session/SessionSyncer.js +13 -0
- package/dist/providers/plugins/sso/session/SessionSyncer.js.map +1 -1
- package/dist/providers/plugins/sso/session/processors/conversations/syncProcessor.js +6 -0
- package/dist/providers/plugins/sso/session/processors/conversations/syncProcessor.js.map +1 -1
- package/dist/providers/plugins/sso/session/processors/metrics/metrics-post-processor.d.ts +0 -6
- package/dist/providers/plugins/sso/session/processors/metrics/metrics-post-processor.d.ts.map +1 -1
- package/dist/providers/plugins/sso/session/processors/metrics/metrics-post-processor.js +28 -19
- package/dist/providers/plugins/sso/session/processors/metrics/metrics-post-processor.js.map +1 -1
- package/dist/telemetry/clients/claude-desktop/claude-desktop.discovery.d.ts.map +1 -1
- package/dist/telemetry/clients/claude-desktop/claude-desktop.discovery.js +13 -1
- package/dist/telemetry/clients/claude-desktop/claude-desktop.discovery.js.map +1 -1
- package/dist/telemetry/clients/claude-desktop/claude-desktop.paths.d.ts +12 -0
- package/dist/telemetry/clients/claude-desktop/claude-desktop.paths.d.ts.map +1 -1
- package/dist/telemetry/clients/claude-desktop/claude-desktop.paths.js +28 -1
- package/dist/telemetry/clients/claude-desktop/claude-desktop.paths.js.map +1 -1
- package/dist/utils/interactive.d.ts +14 -0
- package/dist/utils/interactive.d.ts.map +1 -0
- package/dist/utils/interactive.js +16 -0
- package/dist/utils/interactive.js.map +1 -0
- package/package.json +6 -4
- package/scripts/copy-plugins.js +6 -0
|
@@ -4,23 +4,29 @@
|
|
|
4
4
|
* Centralizes logic for displaying auth errors and prompting for re-authentication
|
|
5
5
|
*/
|
|
6
6
|
import chalk from 'chalk';
|
|
7
|
+
import { isNonInteractiveEnvironment } from '../../utils/interactive.js';
|
|
7
8
|
/**
|
|
8
9
|
* Handle authentication validation failure
|
|
9
10
|
*
|
|
10
|
-
* Prompts for re-authentication if available
|
|
11
|
+
* Prompts for re-authentication if available and an interactive TTY is
|
|
12
|
+
* attached. In a non-interactive environment (no TTY — CI, automation,
|
|
13
|
+
* piped input) the interactive prompt is skipped entirely to avoid hanging
|
|
14
|
+
* or crashing (ERR_USE_AFTER_CLOSE); the provider is treated the same way
|
|
15
|
+
* as one with no promptForReauth implementation at all.
|
|
16
|
+
*
|
|
11
17
|
* Returns true if re-authentication succeeded, false otherwise.
|
|
12
18
|
*
|
|
13
19
|
* @param validationResult - The validation result from validateAuth()
|
|
14
20
|
* @param setupSteps - Provider setup steps (for promptForReauth)
|
|
15
21
|
* @param config - Provider configuration
|
|
16
|
-
* @returns True if re-authentication succeeded, false if declined or not available
|
|
22
|
+
* @returns True if re-authentication succeeded, false if declined, skipped, or not available
|
|
17
23
|
*/
|
|
18
24
|
export async function handleAuthValidationFailure(validationResult, setupSteps, config) {
|
|
19
|
-
// Prompt for re-auth if provider supports it
|
|
20
|
-
if (setupSteps?.promptForReauth) {
|
|
25
|
+
// Prompt for re-auth if the provider supports it AND we can actually prompt
|
|
26
|
+
if (setupSteps?.promptForReauth && !isNonInteractiveEnvironment()) {
|
|
21
27
|
return await setupSteps.promptForReauth(config);
|
|
22
28
|
}
|
|
23
|
-
// No re-auth available, show full error with instructions
|
|
29
|
+
// No re-auth available (or no TTY to prompt on), show full error with instructions
|
|
24
30
|
console.log(chalk.red(`\n✗ ${validationResult.error}\n`));
|
|
25
31
|
return false;
|
|
26
32
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth-validation.js","sourceRoot":"","sources":["../../../src/providers/core/auth-validation.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"auth-validation.js","sourceRoot":"","sources":["../../../src/providers/core/auth-validation.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,OAAO,EAAE,2BAA2B,EAAE,MAAM,4BAA4B,CAAC;AAEzE;;;;;;;;;;;;;;;GAeG;AACH,MAAM,CAAC,KAAK,UAAU,2BAA2B,CAC/C,gBAAsC,EACtC,UAAqC,EACrC,MAA4B;IAE5B,4EAA4E;IAC5E,IAAI,UAAU,EAAE,eAAe,IAAI,CAAC,2BAA2B,EAAE,EAAE,CAAC;QAClE,OAAO,MAAM,UAAU,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC;IAClD,CAAC;IAED,mFAAmF;IACnF,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,gBAAgB,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC;IAC1D,OAAO,KAAK,CAAC;AACf,CAAC"}
|
|
@@ -8,15 +8,20 @@
|
|
|
8
8
|
* 1. Models that DO NOT support thinking (e.g. claude-haiku-4-5, 4-6):
|
|
9
9
|
* → strips the thinking field entirely to prevent API errors
|
|
10
10
|
*
|
|
11
|
-
* 2. Models that require adaptive thinking API (e.g. claude-opus-4-7
|
|
11
|
+
* 2. Models that require adaptive thinking API (e.g. claude-opus-4-7+, claude-sonnet-5):
|
|
12
12
|
* → "enabled" → thinking: { type: "adaptive" } + output_config.effort
|
|
13
|
-
* → "disabled" → delete the
|
|
13
|
+
* → "disabled" → either preserve or delete the field depending on model support
|
|
14
|
+
*
|
|
15
|
+
* 3. Models that deprecate sampling parameters (e.g. claude-sonnet-5):
|
|
16
|
+
* → strips temperature / top_p / top_k entirely to prevent API errors
|
|
14
17
|
*
|
|
15
18
|
* Problem: Claude Code sends `thinking: { type: "enabled", budget_tokens: N }`.
|
|
16
19
|
* - Haiku models reject thinking field with HTTP 400
|
|
17
20
|
* - Opus 4-7+ requires adaptive thinking format with output_config.effort
|
|
21
|
+
* - Sonnet 5 rejects manual extended thinking and sampling parameters
|
|
18
22
|
*
|
|
19
|
-
* Scope: Enabled for codemie-claude (Claude Code via SSO proxy)
|
|
23
|
+
* Scope: Enabled for codemie-claude (Claude Code via SSO proxy), codemie-copilot
|
|
24
|
+
* (GitHub Copilot CLI via BYOK Anthropic shape), and claude-desktop (Desktop 3P mode).
|
|
20
25
|
*
|
|
21
26
|
* To add model support: update NO_THINKING_MODEL_PATTERNS or ADAPTIVE_THINKING_MODEL_PATTERNS.
|
|
22
27
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"claude-request-normalizer.plugin.d.ts","sourceRoot":"","sources":["../../../../../../src/providers/plugins/sso/proxy/plugins/claude-request-normalizer.plugin.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"claude-request-normalizer.plugin.d.ts","sourceRoot":"","sources":["../../../../../../src/providers/plugins/sso/proxy/plugins/claude-request-normalizer.plugin.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAqI1E,qBAAa,6BAA8B,YAAW,WAAW;IAC/D,EAAE,SAA8C;IAChD,IAAI,SAA+B;IACnC,OAAO,SAAW;IAClB,QAAQ,SAAM;IAER,iBAAiB,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,gBAAgB,CAAC;CAS3E"}
|
|
@@ -8,15 +8,20 @@
|
|
|
8
8
|
* 1. Models that DO NOT support thinking (e.g. claude-haiku-4-5, 4-6):
|
|
9
9
|
* → strips the thinking field entirely to prevent API errors
|
|
10
10
|
*
|
|
11
|
-
* 2. Models that require adaptive thinking API (e.g. claude-opus-4-7
|
|
11
|
+
* 2. Models that require adaptive thinking API (e.g. claude-opus-4-7+, claude-sonnet-5):
|
|
12
12
|
* → "enabled" → thinking: { type: "adaptive" } + output_config.effort
|
|
13
|
-
* → "disabled" → delete the
|
|
13
|
+
* → "disabled" → either preserve or delete the field depending on model support
|
|
14
|
+
*
|
|
15
|
+
* 3. Models that deprecate sampling parameters (e.g. claude-sonnet-5):
|
|
16
|
+
* → strips temperature / top_p / top_k entirely to prevent API errors
|
|
14
17
|
*
|
|
15
18
|
* Problem: Claude Code sends `thinking: { type: "enabled", budget_tokens: N }`.
|
|
16
19
|
* - Haiku models reject thinking field with HTTP 400
|
|
17
20
|
* - Opus 4-7+ requires adaptive thinking format with output_config.effort
|
|
21
|
+
* - Sonnet 5 rejects manual extended thinking and sampling parameters
|
|
18
22
|
*
|
|
19
|
-
* Scope: Enabled for codemie-claude (Claude Code via SSO proxy)
|
|
23
|
+
* Scope: Enabled for codemie-claude (Claude Code via SSO proxy), codemie-copilot
|
|
24
|
+
* (GitHub Copilot CLI via BYOK Anthropic shape), and claude-desktop (Desktop 3P mode).
|
|
20
25
|
*
|
|
21
26
|
* To add model support: update NO_THINKING_MODEL_PATTERNS or ADAPTIVE_THINKING_MODEL_PATTERNS.
|
|
22
27
|
*/
|
|
@@ -35,6 +40,7 @@ const NO_THINKING_MODEL_PATTERNS = [
|
|
|
35
40
|
*/
|
|
36
41
|
const ADAPTIVE_THINKING_MODEL_PATTERNS = [
|
|
37
42
|
/claude-opus-4-[7-9](?:[^0-9]|$)/i, // claude-opus-4-7/8/9 and date-tagged variants (e.g. claude-opus-4-7-20250514); excludes claude-opus-4-70+
|
|
43
|
+
/claude-sonnet-5(?:[^0-9]|$)/i, // claude-sonnet-5 and date-tagged variants
|
|
38
44
|
];
|
|
39
45
|
function modelDisablesThinking(modelName) {
|
|
40
46
|
return NO_THINKING_MODEL_PATTERNS.some(p => p.test(modelName));
|
|
@@ -42,6 +48,12 @@ function modelDisablesThinking(modelName) {
|
|
|
42
48
|
function modelRequiresAdaptiveThinking(modelName) {
|
|
43
49
|
return ADAPTIVE_THINKING_MODEL_PATTERNS.some(p => p.test(modelName));
|
|
44
50
|
}
|
|
51
|
+
function modelPreservesDisabledThinking(modelName) {
|
|
52
|
+
return /claude-sonnet-5(?:[^0-9]|$)/i.test(modelName);
|
|
53
|
+
}
|
|
54
|
+
function modelDisablesSamplingParameters(modelName) {
|
|
55
|
+
return /claude-sonnet-5(?:[^0-9]|$)/i.test(modelName);
|
|
56
|
+
}
|
|
45
57
|
/**
|
|
46
58
|
* Map legacy budget_tokens to the closest output_config.effort level.
|
|
47
59
|
*
|
|
@@ -89,13 +101,34 @@ function handleAdaptiveThinkingTransform(body, model) {
|
|
|
89
101
|
logger.debug(`[claude-request-normalizer] Transformed thinking: "enabled" → "adaptive", effort="${effort}" for model: ${model}`);
|
|
90
102
|
}
|
|
91
103
|
else {
|
|
104
|
+
if (modelPreservesDisabledThinking(model)) {
|
|
105
|
+
logger.debug(`[claude-request-normalizer] Preserved thinking.type="disabled" for model: ${model}`);
|
|
106
|
+
return false;
|
|
107
|
+
}
|
|
92
108
|
delete body.thinking;
|
|
93
109
|
logger.debug(`[claude-request-normalizer] Removed unsupported thinking.type="disabled" for model: ${model}`);
|
|
94
110
|
}
|
|
95
111
|
return true;
|
|
96
112
|
}
|
|
113
|
+
function handleDeprecatedSamplingParams(body, model) {
|
|
114
|
+
if (!modelDisablesSamplingParameters(model)) {
|
|
115
|
+
return false;
|
|
116
|
+
}
|
|
117
|
+
const stripped = [];
|
|
118
|
+
for (const key of ['temperature', 'top_p', 'top_k']) {
|
|
119
|
+
if (key in body) {
|
|
120
|
+
delete body[key];
|
|
121
|
+
stripped.push(key);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
if (stripped.length === 0) {
|
|
125
|
+
return false;
|
|
126
|
+
}
|
|
127
|
+
logger.debug(`[claude-request-normalizer] Stripped deprecated sampling params for model ${model}: ${stripped.join(', ')}`);
|
|
128
|
+
return true;
|
|
129
|
+
}
|
|
97
130
|
/** Agents whose Claude API requests need thinking normalization */
|
|
98
|
-
const ALLOWED_AGENTS = ['codemie-claude', 'claude-desktop'];
|
|
131
|
+
const ALLOWED_AGENTS = ['codemie-claude', 'codemie-copilot', 'claude-desktop'];
|
|
99
132
|
export class ClaudeRequestNormalizerPlugin {
|
|
100
133
|
id = '@codemie/proxy-claude-request-normalizer';
|
|
101
134
|
name = 'Claude Request Normalizer';
|
|
@@ -124,17 +157,19 @@ class ClaudeRequestNormalizerInterceptor {
|
|
|
124
157
|
try {
|
|
125
158
|
const bodyStr = context.requestBody.toString('utf-8');
|
|
126
159
|
const body = JSON.parse(bodyStr);
|
|
127
|
-
if (!body.thinking) {
|
|
128
|
-
return;
|
|
129
|
-
}
|
|
130
160
|
const model = (typeof body.model === 'string' && body.model) || this.configModel || '';
|
|
131
161
|
if (!model) {
|
|
132
162
|
return;
|
|
133
163
|
}
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
164
|
+
const modifiedBySampling = handleDeprecatedSamplingParams(body, model);
|
|
165
|
+
let modifiedByThinking = false;
|
|
166
|
+
if (body.thinking) {
|
|
167
|
+
// Chain handlers: first match wins and modifies body
|
|
168
|
+
modifiedByThinking =
|
|
169
|
+
handleNoThinkingModels(body, model) ||
|
|
170
|
+
handleAdaptiveThinkingTransform(body, model);
|
|
171
|
+
}
|
|
172
|
+
if (modifiedBySampling || modifiedByThinking) {
|
|
138
173
|
const newBodyStr = JSON.stringify(body);
|
|
139
174
|
context.requestBody = Buffer.from(newBodyStr, 'utf-8');
|
|
140
175
|
context.headers['content-length'] = String(context.requestBody.length);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"claude-request-normalizer.plugin.js","sourceRoot":"","sources":["../../../../../../src/providers/plugins/sso/proxy/plugins/claude-request-normalizer.plugin.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"claude-request-normalizer.plugin.js","sourceRoot":"","sources":["../../../../../../src/providers/plugins/sso/proxy/plugins/claude-request-normalizer.plugin.ts"],"names":[],"mappings":"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"}
|
package/dist/providers/plugins/sso/proxy/plugins/codex-encrypted-content-sanitizer.plugin.d.ts
CHANGED
|
@@ -2,20 +2,30 @@
|
|
|
2
2
|
* Encrypted Content Sanitizer
|
|
3
3
|
* Priority: 16 (after generic request sanitizer, before header injection)
|
|
4
4
|
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
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
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
* cross-turn
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
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 { ProxyPlugin, PluginContext, ProxyInterceptor } from './types.js';
|
|
21
31
|
export declare class CodexEncryptedContentSanitizerPlugin implements ProxyPlugin {
|
package/dist/providers/plugins/sso/proxy/plugins/codex-encrypted-content-sanitizer.plugin.d.ts.map
CHANGED
|
@@ -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
|
|
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"}
|
package/dist/providers/plugins/sso/proxy/plugins/codex-encrypted-content-sanitizer.plugin.js
CHANGED
|
@@ -2,29 +2,52 @@
|
|
|
2
2
|
* Encrypted Content Sanitizer
|
|
3
3
|
* Priority: 16 (after generic request sanitizer, before header injection)
|
|
4
4
|
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
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
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
* cross-turn
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
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 (
|
|
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
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
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);
|
package/dist/providers/plugins/sso/proxy/plugins/codex-encrypted-content-sanitizer.plugin.js.map
CHANGED
|
@@ -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":"AAAA
|
|
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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"}
|
package/dist/providers/plugins/sso/proxy/plugins/copilot-encrypted-content-sanitizer.plugin.d.ts
ADDED
|
@@ -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
|
package/dist/providers/plugins/sso/proxy/plugins/copilot-encrypted-content-sanitizer.plugin.d.ts.map
ADDED
|
@@ -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"}
|
package/dist/providers/plugins/sso/proxy/plugins/copilot-encrypted-content-sanitizer.plugin.js
ADDED
|
@@ -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
|
package/dist/providers/plugins/sso/proxy/plugins/copilot-encrypted-content-sanitizer.plugin.js.map
ADDED
|
@@ -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":"AAAA;;;;;;GAMG;AAIH,OAAO,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAChE,OAAO,EAAE,MAAM,EAAE,MAAM,gCAAgC,CAAC;AAExD,MAAM,OAAO,qBAAqB;IAChC,EAAE,GAAG,wBAAwB,CAAC;IAC9B,IAAI,GAAG,kBAAkB,CAAC;IAC1B,OAAO,GAAG,OAAO,CAAC;IAClB,QAAQ,GAAG,EAAE,CAAC;IAEd,KAAK,CAAC,iBAAiB,CAAC,OAAsB;QAC5C,OAAO,IAAI,0BAA0B,CAAC,OAAO,CAAC,CAAC;IACjD,CAAC;CACF;AAED,MAAM,0BAA0B;IAGV;IAFpB,IAAI,GAAG,kBAAkB,CAAC;IAE1B,YAAoB,OAAsB;QAAtB,YAAO,GAAP,OAAO,CAAe;IAAG,CAAC;IAE9C,KAAK,CAAC,SAAS,CAAC,OAAqB;QACnC,iCAAiC;QACjC,OAAO,CAAC,OAAO,CAAC,sBAAsB,CAAC,GAAG,OAAO,CAAC,SAAS,CAAC;QAC5D,OAAO,CAAC,OAAO,CAAC,sBAAsB,CAAC,GAAG,OAAO,CAAC,SAAS,CAAC;QAE5D,wEAAwE;QACxE,+DAA+D;QAC/D,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,UAAU,KAAK,eAAe,EAAE,CAAC;
|
|
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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"}
|