@rynfar/meridian 1.68.0 → 1.69.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 (38) hide show
  1. package/dist/{cli-0zhb8ss4.js → cli-x1sv3bqf.js} +897 -504
  2. package/dist/{cli-sh8bzdwe.js → cli-zdbv40d5.js} +26 -7
  3. package/dist/cli.js +4 -4
  4. package/dist/meridian/index.js +252 -0
  5. package/dist/meridian/package.json +6 -0
  6. package/dist/proxy/adapter.d.ts +16 -0
  7. package/dist/proxy/adapter.d.ts.map +1 -1
  8. package/dist/proxy/adapters/claudecode.d.ts +23 -0
  9. package/dist/proxy/adapters/claudecode.d.ts.map +1 -1
  10. package/dist/proxy/adapters/passthrough.d.ts.map +1 -1
  11. package/dist/proxy/errors.d.ts +2 -0
  12. package/dist/proxy/errors.d.ts.map +1 -1
  13. package/dist/proxy/openaiResponses.d.ts +106 -3
  14. package/dist/proxy/openaiResponses.d.ts.map +1 -1
  15. package/dist/proxy/passthroughEarlyStop.d.ts +3 -3
  16. package/dist/proxy/passthroughEarlyStop.d.ts.map +1 -1
  17. package/dist/proxy/passthroughTools.d.ts +63 -2
  18. package/dist/proxy/passthroughTools.d.ts.map +1 -1
  19. package/dist/proxy/query.d.ts +3 -0
  20. package/dist/proxy/query.d.ts.map +1 -1
  21. package/dist/proxy/server.d.ts.map +1 -1
  22. package/dist/proxy/session/cache.d.ts +20 -3
  23. package/dist/proxy/session/cache.d.ts.map +1 -1
  24. package/dist/proxy/session/lineage.d.ts +56 -0
  25. package/dist/proxy/session/lineage.d.ts.map +1 -1
  26. package/dist/proxy/session/processIncarnation.d.ts +55 -0
  27. package/dist/proxy/session/processIncarnation.d.ts.map +1 -1
  28. package/dist/proxy/setup.d.ts +12 -2
  29. package/dist/proxy/setup.d.ts.map +1 -1
  30. package/dist/proxy/transforms/codex.d.ts +12 -0
  31. package/dist/proxy/transforms/codex.d.ts.map +1 -1
  32. package/dist/server.js +2 -2
  33. package/dist/{setup-knvctar4.js → setup-b3ymd9z8.js} +3 -1
  34. package/dist/telemetry/index.d.ts.map +1 -1
  35. package/package.json +4 -4
  36. package/plugin/meridian/index.js +1 -0
  37. package/plugin/meridian/package.json +6 -0
  38. package/plugin/meridian.ts +1 -1
@@ -720,6 +720,15 @@ class UnparseableConfigError extends Error {
720
720
  }
721
721
  }
722
722
 
723
+ class MissingV1PluginError extends Error {
724
+ expectedPath;
725
+ constructor(expectedPath) {
726
+ super(`OpenCode V1 plugin bundle not found at ${expectedPath}`);
727
+ this.expectedPath = expectedPath;
728
+ this.name = "MissingV1PluginError";
729
+ }
730
+ }
731
+
723
732
  class MissingV2PluginError extends Error {
724
733
  expectedPath;
725
734
  constructor(expectedPath) {
@@ -771,14 +780,24 @@ function siblingOpencodeConfigPath(configPath) {
771
780
  return;
772
781
  }
773
782
  function findPluginPath(fromUrl) {
774
- const dir = dirname2(fileURLToPath(fromUrl));
775
- return join2(dir, "..", "plugin", "meridian.ts");
783
+ const entryPath = fileURLToPath(fromUrl);
784
+ const dir = dirname2(entryPath);
785
+ if (entryPath.endsWith(".ts")) {
786
+ const sourcePlugin = join2(dir, "..", "plugin", "meridian");
787
+ if (hasPluginPackageEntry(sourcePlugin))
788
+ return sourcePlugin;
789
+ throw new MissingV1PluginError(sourcePlugin);
790
+ }
791
+ const bundledPlugin = join2(dir, "meridian");
792
+ if (hasPluginPackageEntry(bundledPlugin))
793
+ return bundledPlugin;
794
+ throw new MissingV1PluginError(bundledPlugin);
776
795
  }
777
796
  var SUPPORTED_OPENCODE_V2_VERSIONS = new Set([
778
797
  "0.0.0-beta-18314",
779
798
  "0.0.0-beta-18866"
780
799
  ]);
781
- function hasV2PluginEntry(path) {
800
+ function hasPluginPackageEntry(path) {
782
801
  try {
783
802
  if (!statSync(join2(path, "index.js"), { throwIfNoEntry: false })?.isFile())
784
803
  return false;
@@ -796,12 +815,12 @@ function findV2PluginPath(fromUrl) {
796
815
  const dir = dirname2(entryPath);
797
816
  if (entryPath.endsWith(".ts")) {
798
817
  const sourcePlugin = join2(dir, "..", "plugin", "meridian-v2");
799
- if (hasV2PluginEntry(sourcePlugin))
818
+ if (hasPluginPackageEntry(sourcePlugin))
800
819
  return sourcePlugin;
801
820
  throw new MissingV2PluginError(sourcePlugin);
802
821
  }
803
822
  const bundledPlugin = join2(dir, "meridian-v2");
804
- if (hasV2PluginEntry(bundledPlugin))
823
+ if (hasPluginPackageEntry(bundledPlugin))
805
824
  return bundledPlugin;
806
825
  throw new MissingV2PluginError(bundledPlugin);
807
826
  }
@@ -856,7 +875,7 @@ function isMeridianEntry(entry) {
856
875
  const packageName = pluginEntryPackage(entry);
857
876
  if (!packageName)
858
877
  return false;
859
- return STALE_PATTERNS.some((pattern) => packageName.includes(pattern)) || packageName.includes("meridian.ts") || packageName.includes("meridian-v2.") || packageName.endsWith("/meridian-v2") || packageName.includes("@rynfar/meridian");
878
+ return STALE_PATTERNS.some((pattern) => packageName.includes(pattern)) || packageName.includes("meridian.ts") || packageName.includes("meridian-v2.") || packageName.endsWith("/meridian-v2") || /[\\/]meridian$/.test(packageName) || packageName.includes("@rynfar/meridian");
860
879
  }
861
880
  function checkPluginConfigured(configPath, expectedPluginPath) {
862
881
  const selectedPath = configPath ?? findOpencodeConfigPath();
@@ -952,4 +971,4 @@ function runSetup(pluginPath, configPath, generation = "v1") {
952
971
  return { configPath: path, pluginPath, alreadyConfigured, removedStale, created: false };
953
972
  }
954
973
 
955
- export { LRUMap, PRIORITY_ATTESTATION_HEADER, verifyPriorityAttestation, init_priorityAttestation, UnparseableConfigError, MissingV2PluginError, DuplicateMeridianConfigError, findOpencodeConfigPath, findPluginPath, SUPPORTED_OPENCODE_V2_VERSIONS, findV2PluginPath, classifyOpenCodeVersion, detectOpenCodeGeneration, pluginPathForGeneration, checkPluginConfigured, clearPluginlessWarnings, notePluginlessOpenCodeRequest, runSetup };
974
+ export { LRUMap, PRIORITY_ATTESTATION_HEADER, verifyPriorityAttestation, init_priorityAttestation, UnparseableConfigError, MissingV1PluginError, MissingV2PluginError, DuplicateMeridianConfigError, findOpencodeConfigPath, findPluginPath, SUPPORTED_OPENCODE_V2_VERSIONS, findV2PluginPath, classifyOpenCodeVersion, detectOpenCodeGeneration, pluginPathForGeneration, checkPluginConfigured, clearPluginlessWarnings, notePluginlessOpenCodeRequest, runSetup };
package/dist/cli.js CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  startProxyServer
4
- } from "./cli-0zhb8ss4.js";
4
+ } from "./cli-x1sv3bqf.js";
5
5
  import"./cli-5jxyma6z.js";
6
6
  import"./cli-sry5aqdj.js";
7
7
  import"./cli-8yp89fan.js";
@@ -10,7 +10,7 @@ import {
10
10
  } from "./cli-9e5cxp89.js";
11
11
  import"./cli-khhjyk04.js";
12
12
  import"./cli-vj9cv18n.js";
13
- import"./cli-sh8bzdwe.js";
13
+ import"./cli-zdbv40d5.js";
14
14
  import {
15
15
  __require
16
16
  } from "./cli-p9swy5t3.js";
@@ -93,7 +93,7 @@ if (args[0] === "setup") {
93
93
  runSetup,
94
94
  SUPPORTED_OPENCODE_V2_VERSIONS,
95
95
  UnparseableConfigError
96
- } = await import("./setup-knvctar4.js");
96
+ } = await import("./setup-b3ymd9z8.js");
97
97
  const forceV1 = args.includes("--v1");
98
98
  const forceV2 = args.includes("--v2");
99
99
  if (forceV1 && forceV2) {
@@ -205,7 +205,7 @@ async function runCli(start = startProxyServer, runAuthCheck = async () => {
205
205
  return execFile(claudePath, ["auth", "status"], { timeout: 5000 });
206
206
  }) {
207
207
  try {
208
- const { findOpencodeConfigPath, checkPluginConfigured, findPluginPath } = await import("./setup-knvctar4.js");
208
+ const { findOpencodeConfigPath, checkPluginConfigured, findPluginPath } = await import("./setup-b3ymd9z8.js");
209
209
  const configPath = findOpencodeConfigPath();
210
210
  const { existsSync } = await import("fs");
211
211
  if (existsSync(configPath) && !checkPluginConfigured(configPath)) {
@@ -0,0 +1,252 @@
1
+ // plugin/priority-attestation.ts
2
+ import { createHash, createHmac } from "node:crypto";
3
+ import { readFileSync } from "node:fs";
4
+ import { homedir } from "node:os";
5
+ import { join } from "node:path";
6
+ var PRIORITY_ATTESTATION_HEADER = "x-meridian-opencode-turn";
7
+ var PRIORITY_ATTESTATION_KEY_ENV = "MERIDIAN_OPENCODE_ATTESTATION_KEY";
8
+ var PRIORITY_ATTESTATION_KEY_FILE = "opencode-turn.key";
9
+ var TOKEN_PREFIX = "v1";
10
+ var MAC_DOMAIN = "meridian.opencode.turn.v1\x00";
11
+ var TURN_DOMAIN = "meridian.opencode.human.v1\x00";
12
+ var MAX_HEADER_BYTES = 768;
13
+ var MAX_PAYLOAD_BYTES = 384;
14
+ var TURN_DIGEST_PATTERN = /^[A-Za-z0-9_-]{43}$/;
15
+ var SAFE_ID_PATTERN = /^[A-Za-z0-9._:-]{1,128}$/;
16
+ function configDirectory() {
17
+ return process.env.MERIDIAN_CONFIG_DIR ?? join(homedir(), ".config", "meridian");
18
+ }
19
+ function priorityAttestationKeyPath() {
20
+ return join(configDirectory(), PRIORITY_ATTESTATION_KEY_FILE);
21
+ }
22
+ function isSafeAgentId(value) {
23
+ return value.length >= 1 && value.length <= 64 && value.trim() === value && /^[\x20-\x7E]+$/.test(value);
24
+ }
25
+ function decodeCanonicalBase64Url(raw) {
26
+ if (!/^[A-Za-z0-9_-]+$/.test(raw))
27
+ return;
28
+ const decoded = Buffer.from(raw, "base64url");
29
+ return decoded.toString("base64url") === raw ? decoded : undefined;
30
+ }
31
+ function decodePriorityAttestationKey(raw) {
32
+ if (raw === undefined)
33
+ return;
34
+ const normalized = raw.trim();
35
+ const decoded = decodeCanonicalBase64Url(normalized);
36
+ return decoded?.length === 32 ? decoded : undefined;
37
+ }
38
+ function loadPriorityAttestationKey() {
39
+ const fromEnv = process.env[PRIORITY_ATTESTATION_KEY_ENV];
40
+ if (fromEnv !== undefined)
41
+ return decodePriorityAttestationKey(fromEnv);
42
+ try {
43
+ return decodePriorityAttestationKey(readFileSync(priorityAttestationKeyPath(), "utf8"));
44
+ } catch {
45
+ return;
46
+ }
47
+ }
48
+ function computePriorityTurnDigest(input) {
49
+ if (!SAFE_ID_PATTERN.test(input.sessionId) || !SAFE_ID_PATTERN.test(input.humanMessageId)) {
50
+ return;
51
+ }
52
+ return createHash("sha256").update(TURN_DOMAIN).update(input.generation).update("\x00").update(input.sessionId).update("\x00").update(input.humanMessageId).digest("base64url");
53
+ }
54
+ function createPriorityAttestation(input, key = loadPriorityAttestationKey() ?? Buffer.alloc(0)) {
55
+ if (key.length !== 32)
56
+ return;
57
+ if (!SAFE_ID_PATTERN.test(input.sessionId) || !isSafeAgentId(input.agentId))
58
+ return;
59
+ const turnDigest = computePriorityTurnDigest(input);
60
+ if (!turnDigest || !TURN_DIGEST_PATTERN.test(turnDigest))
61
+ return;
62
+ const issuedAt = input.issuedAt;
63
+ if (!Number.isSafeInteger(issuedAt) || issuedAt < 0)
64
+ return;
65
+ const payload = JSON.stringify({
66
+ v: 1,
67
+ g: input.generation,
68
+ s: input.sessionId,
69
+ a: input.agentId,
70
+ t: turnDigest,
71
+ iat: issuedAt
72
+ });
73
+ if (Buffer.byteLength(payload) > MAX_PAYLOAD_BYTES)
74
+ return;
75
+ const encodedPayload = Buffer.from(payload).toString("base64url");
76
+ const mac = createHmac("sha256", key).update(MAC_DOMAIN).update(payload).digest("base64url");
77
+ const token = `${TOKEN_PREFIX}.${encodedPayload}.${mac}`;
78
+ return Buffer.byteLength(token) <= MAX_HEADER_BYTES ? token : undefined;
79
+ }
80
+ function deleteHeader(headers, name) {
81
+ if (headers instanceof Headers) {
82
+ headers.delete(name);
83
+ return;
84
+ }
85
+ const lower = name.toLowerCase();
86
+ for (const key of Object.keys(headers)) {
87
+ if (key.toLowerCase() === lower)
88
+ delete headers[key];
89
+ }
90
+ }
91
+ function getHeader(headers, name) {
92
+ if (headers instanceof Headers)
93
+ return headers.get(name) ?? undefined;
94
+ const lower = name.toLowerCase();
95
+ for (const [key, value] of Object.entries(headers)) {
96
+ if (key.toLowerCase() === lower)
97
+ return value;
98
+ }
99
+ return;
100
+ }
101
+ function setHeader(headers, name, value) {
102
+ deleteHeader(headers, name);
103
+ if (headers instanceof Headers)
104
+ headers.set(name, value);
105
+ else
106
+ headers[name] = value;
107
+ }
108
+
109
+ // plugin/meridian.ts
110
+ var BUILTIN_AGENT_MODES = {
111
+ build: "primary",
112
+ plan: "primary",
113
+ general: "subagent",
114
+ explore: "subagent",
115
+ title: "subagent",
116
+ summary: "subagent",
117
+ compaction: "subagent"
118
+ };
119
+ var INTERNAL_AGENT_IDS = new Set(["title", "summary", "compaction"]);
120
+ var ROOT_SESSION_CACHE_MAX = 256;
121
+ var ROOT_SESSION_CACHE_TTL_MS = 5000;
122
+ var LOOKUP_TIMEOUT_MS = 250;
123
+ function isRecord(value) {
124
+ return typeof value === "object" && value !== null && !Array.isArray(value);
125
+ }
126
+ async function withTimeout(pending, timeoutMs) {
127
+ let timer;
128
+ const timedOut = new Promise((resolve) => {
129
+ timer = setTimeout(() => resolve(undefined), timeoutMs);
130
+ timer.unref?.();
131
+ });
132
+ try {
133
+ return await Promise.race([pending, timedOut]);
134
+ } finally {
135
+ if (timer)
136
+ clearTimeout(timer);
137
+ }
138
+ }
139
+ var MeridianPlugin = async (pluginInput) => {
140
+ let configAgents = {};
141
+ const rootSessionCache = new Map;
142
+ const resolve = (agent) => {
143
+ if (typeof agent === "object" && agent !== null) {
144
+ return { name: agent.name ?? "unknown", mode: agent.mode ?? "primary" };
145
+ }
146
+ const name = String(agent);
147
+ return { name, mode: configAgents[name]?.mode ?? BUILTIN_AGENT_MODES[name] ?? "primary" };
148
+ };
149
+ const isStrictVisiblePrimary = (agent) => {
150
+ const name = typeof agent === "string" ? agent : agent.name;
151
+ if (!name || INTERNAL_AGENT_IDS.has(name))
152
+ return false;
153
+ if (typeof agent === "object") {
154
+ return agent.mode === "primary" && agent.hidden !== true;
155
+ }
156
+ const configured = configAgents[name];
157
+ if (configured)
158
+ return configured.mode === "primary" && configured.hidden !== true;
159
+ return BUILTIN_AGENT_MODES[name] === "primary";
160
+ };
161
+ const isRootSession = async (sessionID) => {
162
+ const cached = rootSessionCache.get(sessionID);
163
+ if (cached && cached.expiresAt > Date.now())
164
+ return cached.pending;
165
+ const pending = (async () => {
166
+ if (!isRecord(pluginInput) || !isRecord(pluginInput.client))
167
+ return false;
168
+ const sessionApi = pluginInput.client.session;
169
+ if (!isRecord(sessionApi) || typeof sessionApi.get !== "function")
170
+ return false;
171
+ const controller = new AbortController;
172
+ try {
173
+ const lookup = Promise.resolve(Reflect.apply(sessionApi.get, sessionApi, [
174
+ { path: { id: sessionID }, signal: controller.signal }
175
+ ]));
176
+ const result = await withTimeout(lookup, LOOKUP_TIMEOUT_MS);
177
+ if (!isRecord(result))
178
+ return false;
179
+ const data = isRecord(result.data) ? result.data : result;
180
+ return data.id === sessionID && data.parentID === undefined && data.fork === undefined;
181
+ } catch {
182
+ return false;
183
+ } finally {
184
+ controller.abort();
185
+ }
186
+ })();
187
+ rootSessionCache.delete(sessionID);
188
+ rootSessionCache.set(sessionID, { expiresAt: Date.now() + ROOT_SESSION_CACHE_TTL_MS, pending });
189
+ while (rootSessionCache.size > ROOT_SESSION_CACHE_MAX) {
190
+ const oldest = rootSessionCache.keys().next().value;
191
+ if (oldest === undefined)
192
+ break;
193
+ rootSessionCache.delete(oldest);
194
+ }
195
+ const eligible = await pending;
196
+ if (!eligible && rootSessionCache.get(sessionID)?.pending === pending)
197
+ rootSessionCache.delete(sessionID);
198
+ return eligible;
199
+ };
200
+ return {
201
+ config: (cfg) => {
202
+ const next = {};
203
+ for (const [name, def] of Object.entries(cfg?.agent ?? {})) {
204
+ if (!def)
205
+ continue;
206
+ next[name] = {
207
+ ...typeof def.mode === "string" ? { mode: def.mode } : {},
208
+ ...typeof def.hidden === "boolean" ? { hidden: def.hidden } : {}
209
+ };
210
+ }
211
+ configAgents = next;
212
+ },
213
+ "chat.headers": async (incoming, output) => {
214
+ deleteHeader(output.headers, PRIORITY_ATTESTATION_HEADER);
215
+ if (incoming.model.providerID !== "anthropic")
216
+ return;
217
+ setHeader(output.headers, "x-opencode-session", incoming.sessionID);
218
+ setHeader(output.headers, "x-opencode-request", incoming.message.id);
219
+ const { name, mode } = resolve(incoming.agent);
220
+ const safeName = name.replace(/[^\x20-\x7E]/g, "").trim() || "unknown";
221
+ setHeader(output.headers, "x-opencode-agent-mode", mode === "subagent" ? "subagent" : "primary");
222
+ setHeader(output.headers, "x-opencode-agent-name", safeName);
223
+ if (getHeader(output.headers, "x-meridian-profile") !== undefined)
224
+ return;
225
+ if (safeName !== name || !isStrictVisiblePrimary(incoming.agent))
226
+ return;
227
+ const createdAt = incoming.message.time?.created;
228
+ if (typeof createdAt !== "number" || !Number.isSafeInteger(createdAt) || createdAt < 0)
229
+ return;
230
+ const issuedAt = Math.floor(createdAt / 1000);
231
+ if (incoming.message.sessionID !== undefined && incoming.message.sessionID !== incoming.sessionID)
232
+ return;
233
+ if (!await isRootSession(incoming.sessionID))
234
+ return;
235
+ if (!isStrictVisiblePrimary(incoming.agent))
236
+ return;
237
+ const token = createPriorityAttestation({
238
+ generation: "oc1",
239
+ sessionId: incoming.sessionID,
240
+ agentId: safeName,
241
+ humanMessageId: incoming.message.id,
242
+ issuedAt
243
+ });
244
+ if (token)
245
+ setHeader(output.headers, PRIORITY_ATTESTATION_HEADER, token);
246
+ }
247
+ };
248
+ };
249
+ var meridian_default = MeridianPlugin;
250
+ export {
251
+ meridian_default as default
252
+ };
@@ -0,0 +1,6 @@
1
+ {
2
+ "name": "@rynfar/meridian-opencode-v1-plugin",
3
+ "private": true,
4
+ "type": "module",
5
+ "main": "./index.js"
6
+ }
@@ -127,6 +127,22 @@ export interface AgentIdentity {
127
127
  * Tools are registered as `mcp__{name}__{tool}`.
128
128
  */
129
129
  getMcpServerName(): string;
130
+ /**
131
+ * The namespace the CLIENT'S tools are nested under in passthrough mode,
132
+ * where they appear to the model as `mcp__{name}__{tool}`.
133
+ *
134
+ * Deliberately NOT `getMcpServerName()`, which names the server Meridian
135
+ * registers in INTERNAL mode. Reusing that would rename every OpenCode
136
+ * client tool from `mcp__oc__read` to `mcp__opencode__read`, moving the
137
+ * model-visible prompt — and so the prompt cache — for the entire existing
138
+ * user base, and colliding with the `mcp__opencode__*` names
139
+ * `passthroughEarlyStop` excludes precisely because they are internal.
140
+ *
141
+ * Defaults to `oc` when unset, which is what every adapter used before this
142
+ * existed. Override it only where the default actively misleads: `oc` reads
143
+ * as "opencode" to a model on an adapter that is not OpenCode (#893).
144
+ */
145
+ getPassthroughMcpName?(): string;
130
146
  }
131
147
  /**
132
148
  * An agent adapter provides agent-specific configuration to the proxy.
@@ -1 +1 @@
1
- {"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../../src/proxy/adapter.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../../src/proxy/adapter.ts"],"names":[],"mappings":"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"}
@@ -16,6 +16,7 @@
16
16
  * - Parses the client's local CWD via extractClientWorkingDirectory for
17
17
  * fingerprinting and a system-prompt hint (see server.ts + query.ts).
18
18
  */
19
+ import type { Context } from "hono";
19
20
  import type { AgentAdapter } from "../adapter";
20
21
  /**
21
22
  * Session identity declared in `metadata.user_id`.
@@ -48,5 +49,27 @@ export declare function extractClaudeCodeSessionIdentity(body: unknown): ClaudeC
48
49
  export declare function extractClaudeCodeSessionId(body: unknown): string | undefined;
49
50
  /** Extract the immediate parent session key, when the client declares lineage. */
50
51
  export declare function extractClaudeCodeParentSessionId(body: unknown): string | undefined;
52
+ /**
53
+ * Is this request from the Claude Code CLI, whatever adapter is handling it?
54
+ *
55
+ * Claude Code sends `x-claude-code-session-id` on every request — verified
56
+ * against 2.1.266 that it is the CLI session UUID, pinned exactly by
57
+ * `--session-id`. No other client sends it, so it identifies the client even
58
+ * when a gateway has rewritten the User-Agent and the LiteLLM heuristic has
59
+ * already claimed the request.
60
+ *
61
+ * This answers "who owns the tool loop", not "which adapter should run". The
62
+ * header is deliberately NOT used for adapter selection: routing gateway
63
+ * traffic to the claude-code adapter would swap tool handling, MCP naming and
64
+ * prompt shape for every existing LiteLLM user and move their cache prefix.
65
+ *
66
+ * It is also NOT a session key. The CLI reuses one session id across the
67
+ * auxiliary requests it makes alongside a conversation, so keying on it puts
68
+ * two unrelated histories under one key — measured live as
69
+ * `unrelated-history` and an HTTP 400 concurrent conflict, i.e. a hard failure
70
+ * where there had only been a silent inefficiency. See
71
+ * `scripts/e2e-passthrough-claude-code-session.mjs`, which guards that.
72
+ */
73
+ export declare function isClaudeCodeClient(c: Context): boolean;
51
74
  export declare const claudeCodeAdapter: AgentAdapter;
52
75
  //# sourceMappingURL=claudecode.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"claudecode.d.ts","sourceRoot":"","sources":["../../../src/proxy/adapters/claudecode.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AAiC9C;;;;;;;GAOG;AACH,MAAM,WAAW,yBAAyB;IACxC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B;;;;OAIG;IACH,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,CAAA;CAClC;AAED;;;;;;;;GAQG;AACH,wBAAgB,gCAAgC,CAAC,IAAI,EAAE,OAAO,GAAG,yBAAyB,GAAG,SAAS,CA+BrG;AAED,sFAAsF;AACtF,wBAAgB,0BAA0B,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAE5E;AAED,kFAAkF;AAClF,wBAAgB,gCAAgC,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAElF;AAED,eAAO,MAAM,iBAAiB,EAAE,YAqG/B,CAAA"}
1
+ {"version":3,"file":"claudecode.d.ts","sourceRoot":"","sources":["../../../src/proxy/adapters/claudecode.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,MAAM,CAAA;AACnC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AAiC9C;;;;;;;GAOG;AACH,MAAM,WAAW,yBAAyB;IACxC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B;;;;OAIG;IACH,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,CAAA;CAClC;AAED;;;;;;;;GAQG;AACH,wBAAgB,gCAAgC,CAAC,IAAI,EAAE,OAAO,GAAG,yBAAyB,GAAG,SAAS,CA+BrG;AAED,sFAAsF;AACtF,wBAAgB,0BAA0B,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAE5E;AAED,kFAAkF;AAClF,wBAAgB,gCAAgC,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAElF;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,kBAAkB,CAAC,CAAC,EAAE,OAAO,GAAG,OAAO,CAEtD;AAED,eAAO,MAAM,iBAAiB,EAAE,YAqG/B,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"passthrough.d.ts","sourceRoot":"","sources":["../../../src/proxy/adapters/passthrough.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AAiD9C,eAAO,MAAM,kBAAkB,EAAE,YA4EhC,CAAA;AAED,OAAO,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAA;AACjE,OAAO,EAAE,qBAAqB,EAAE,CAAA"}
1
+ {"version":3,"file":"passthrough.d.ts","sourceRoot":"","sources":["../../../src/proxy/adapters/passthrough.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AAiD9C,eAAO,MAAM,kBAAkB,EAAE,YAuFhC,CAAA;AAED,OAAO,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAA;AACjE,OAAO,EAAE,qBAAqB,EAAE,CAAA"}
@@ -25,6 +25,8 @@ export interface ClassifiedError {
25
25
  * - The tier is unrecognized, where the global switch is the only safe advice.
26
26
  */
27
27
  export declare function extendedContextHint(model?: string): string;
28
+ /** True when a turn failed only because it hit the client's output cap. */
29
+ export declare function isOutputTokenCapExceeded(message: string | undefined | null): boolean;
28
30
  /**
29
31
  * Detect specific SDK errors and return helpful messages to the client.
30
32
  *
@@ -1 +1 @@
1
- {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/proxy/errors.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAA;IACd,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,MAAM,CAAA;CAChB;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAc1D;AAqLD;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,eAAe,CA2K7E;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAM3D;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,aAAa,GAAG,iBAAiB,CAAA;AAEtE;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,aAAa,GAAG,SAAS,CAahG;AAED;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAI3E;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAGxD;AAuBD;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,SAAS,IAAI,MAAM,CAEhG;AAED;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,OAAO,CAE5E;AAED;;;;GAIG;AACH,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAGjE;AAED;;;;;GAKG;AACH,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,WAAW,GAAG,cAAc,GAAG,SAAS,GAAG,eAAe,GAAG,kBAAkB,GAAG,SAAS,CAAA;IACnG,sDAAsD;IACtD,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,wDAAwD;IACxD,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,uEAAuE;IACvE,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,wDAAwD;IACxD,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB;;wCAEoC;IACpC,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB;AAuBD;;;;;;GAMG;AACH;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,0BAA0B,CAAC,KAAK,EAAE;IAChD,MAAM,EAAE,cAAc,CAAC,QAAQ,CAAC,CAAA;IAChC,WAAW,EAAE,OAAO,CAAA;IACpB,gBAAgB,EAAE,MAAM,CAAA;IACxB,WAAW,EAAE,OAAO,CAAA;CACrB,GAAG,OAAO,CAYV;AAED,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,MAAM,GAAG,cAAc,CAiEpE;AAED;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAClC,CAAC,EAAE,cAAc,EACjB,GAAG,EAAE;IACH,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,gBAAgB,CAAC,EAAE,OAAO,CAAA;IAC1B,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB,GACA,MAAM,CAYR"}
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/proxy/errors.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAA;IACd,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,MAAM,CAAA;CAChB;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAc1D;AAuID,2EAA2E;AAC3E,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,GAAG,OAAO,CAEpF;AAqFD;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,eAAe,CA2K7E;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAM3D;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,aAAa,GAAG,iBAAiB,CAAA;AAEtE;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,aAAa,GAAG,SAAS,CAahG;AAED;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAI3E;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAGxD;AAuBD;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,SAAS,IAAI,MAAM,CAEhG;AAED;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,OAAO,CAE5E;AAED;;;;GAIG;AACH,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAGjE;AAED;;;;;GAKG;AACH,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,WAAW,GAAG,cAAc,GAAG,SAAS,GAAG,eAAe,GAAG,kBAAkB,GAAG,SAAS,CAAA;IACnG,sDAAsD;IACtD,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,wDAAwD;IACxD,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,uEAAuE;IACvE,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,wDAAwD;IACxD,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB;;wCAEoC;IACpC,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB;AAuBD;;;;;;GAMG;AACH;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,0BAA0B,CAAC,KAAK,EAAE;IAChD,MAAM,EAAE,cAAc,CAAC,QAAQ,CAAC,CAAA;IAChC,WAAW,EAAE,OAAO,CAAA;IACpB,gBAAgB,EAAE,MAAM,CAAA;IACxB,WAAW,EAAE,OAAO,CAAA;CACrB,GAAG,OAAO,CAYV;AAED,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,MAAM,GAAG,cAAc,CAiEpE;AAED;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAClC,CAAC,EAAE,cAAc,EACjB,GAAG,EAAE;IACH,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,gBAAgB,CAAC,EAAE,OAAO,CAAA;IAC1B,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB,GACA,MAAM,CAYR"}
@@ -33,25 +33,54 @@ interface ResponsesMessageItem {
33
33
  interface ResponsesFunctionCallItem {
34
34
  type: "function_call";
35
35
  name: string;
36
+ /** Set when the tool lives in a `namespace` tool entry (an MCP server). */
37
+ namespace?: string;
36
38
  arguments: string;
37
39
  call_id: string;
38
40
  }
41
+ /**
42
+ * `function_call_output.output` is a plain string for shell-style tools and an
43
+ * array of content items for MCP tools (Codex's FunctionCallOutputBody is an
44
+ * untagged Text | ContentItems); custom tool outputs are always strings.
45
+ */
46
+ interface ResponsesOutputContentItem {
47
+ type: "input_text" | "input_image" | "input_audio" | "encrypted_content" | string;
48
+ text?: string;
49
+ image_url?: string;
50
+ }
39
51
  interface ResponsesFunctionCallOutputItem {
40
52
  type: "function_call_output";
41
53
  call_id: string;
54
+ output: string | ResponsesOutputContentItem[];
55
+ }
56
+ /** A freeform (`type:"custom"`) tool call — Codex's `apply_patch`. */
57
+ interface ResponsesCustomToolCallItem {
58
+ type: "custom_tool_call";
59
+ name: string;
60
+ namespace?: string;
61
+ input: string;
62
+ call_id: string;
63
+ }
64
+ interface ResponsesCustomToolCallOutputItem {
65
+ type: "custom_tool_call_output";
66
+ call_id: string;
42
67
  output: string;
43
68
  }
44
69
  interface ResponsesReasoningItem {
45
70
  type: "reasoning";
46
71
  [k: string]: unknown;
47
72
  }
48
- type ResponsesInputItem = ResponsesMessageItem | ResponsesFunctionCallItem | ResponsesFunctionCallOutputItem | ResponsesReasoningItem;
49
- interface ResponsesTool {
50
- type: "function" | string;
73
+ type ResponsesInputItem = ResponsesMessageItem | ResponsesFunctionCallItem | ResponsesFunctionCallOutputItem | ResponsesCustomToolCallItem | ResponsesCustomToolCallOutputItem | ResponsesReasoningItem;
74
+ export interface ResponsesTool {
75
+ type: "function" | "custom" | "namespace" | string;
51
76
  name: string;
52
77
  description?: string;
53
78
  strict?: boolean;
54
79
  parameters?: unknown;
80
+ /** `custom` tools: the freeform grammar Codex expects the input to follow. */
81
+ format?: unknown;
82
+ /** `namespace` tools: the nested function/custom tools of one MCP server. */
83
+ tools?: ResponsesTool[];
55
84
  }
56
85
  export interface ResponsesRequest {
57
86
  model?: string;
@@ -69,6 +98,75 @@ export interface ResponsesRequest {
69
98
  stream?: boolean;
70
99
  [k: string]: unknown;
71
100
  }
101
+ /**
102
+ * Codex (0.15x) ships every MCP server as one `{type:"namespace", name,
103
+ * tools:[…]}` entry with the tool definitions nested inside, and its freeform
104
+ * `apply_patch` as `{type:"custom"}`. Claude sees one flat list of function
105
+ * tools, so each nested or custom tool is exposed under an alias, and the alias
106
+ * table maps Claude's call back onto the exact `{namespace, name}` pair Codex's
107
+ * router resolves (`ToolName::new(namespace, name)` — a flattened name without
108
+ * `namespace` never matches a namespaced tool).
109
+ */
110
+ export interface ResponsesToolAlias {
111
+ namespace?: string;
112
+ name: string;
113
+ kind: "function" | "custom";
114
+ }
115
+ export type ResponsesToolAliases = Map<string, ResponsesToolAlias>;
116
+ export declare const RESPONSES_TOOL_ALIAS_MAX: number;
117
+ /**
118
+ * The Claude-visible name of a tool. Deterministic on (namespace, name): the
119
+ * history Codex replays next turn carries the same pair and must land on the
120
+ * same alias, or the replayed `tool_use` names no longer match the tool set.
121
+ */
122
+ export declare function responsesToolAlias(namespace: string | undefined, name: string): string;
123
+ /**
124
+ * Alias table for a request's tools. Pure and deterministic, so the route can
125
+ * rebuild it for the response side without threading state through the
126
+ * request translator. Top-level function tools keep their own names and are
127
+ * not listed.
128
+ */
129
+ export declare function buildResponsesToolAliases(tools: ResponsesTool[] | undefined): ResponsesToolAliases;
130
+ /** What one Codex turn says about the conversation it belongs to. */
131
+ export interface CodexThreadIdentity {
132
+ /** Conversation key for session resume — the codex adapter's `x-codex-session`. */
133
+ sessionKey?: string;
134
+ /** Concurrency declaration for a turn that is not the thread the user drives. */
135
+ requestSource?: string;
136
+ }
137
+ /**
138
+ * Reads the conversation identity Codex attaches to a turn.
139
+ *
140
+ * `prompt_cache_key` was the only identity this route had (#655), and for the
141
+ * thread a user drives it is exactly that thread's id. A subagent is the case
142
+ * it cannot describe: Codex Desktop spawns one as its own thread, with its own
143
+ * instructions and its own tools, and hands it the *parent's*
144
+ * `prompt_cache_key`. Keyed on that alone two live conversations become one
145
+ * session — the subagent's first turn rebinds the key to its own SDK session,
146
+ * and the parent's next turn then reads as a rewrite of it: refused as a
147
+ * concurrent conflict when it loses the session-turn race, replayed from
148
+ * scratch when it wins.
149
+ *
150
+ * `x-codex-turn-metadata` names the thread itself, so the thread id is the
151
+ * honest key: identical to `prompt_cache_key` for a user thread — this
152
+ * re-anchors no existing session — and distinct for every spawned one.
153
+ * `thread_source` carries the same fact independently, so a turn from a
154
+ * spawned thread also declares a concurrent flow and is admitted rather than
155
+ * refused should a client ever reuse one id across flows. `fork-` and not
156
+ * `subagent-`: the tier a Codex subagent runs on is the client's choice, and
157
+ * a concurrency declaration must not silently rewrite it.
158
+ *
159
+ * `request_kind` is the third signal. Codex runs side requests against the
160
+ * same thread id — `compact` carries the whole history with no tools to
161
+ * summarise it, and the binary also names `title`, `summary`, `review`,
162
+ * `memory` — and none of them is the conversation: keyed on the thread alone
163
+ * a compaction lands on the conversation's session as a rewrite of it.
164
+ * Observed live: a 379-message `compact` under a live thread's key. Any kind
165
+ * other than `turn` therefore gets its own key beside the thread's and
166
+ * declares its own flow; a kind Codex has not sent yet is handled the same
167
+ * way, since the property that matters — not being the turn — is shared.
168
+ */
169
+ export declare function resolveCodexThreadIdentity(body: ResponsesRequest, metadataHeader?: string): CodexThreadIdentity;
72
170
  /**
73
171
  * Translate a Responses request to an Anthropic /v1/messages body.
74
172
  * Returns null when `input` is missing (invalid request).
@@ -86,6 +184,11 @@ export interface ResponsesCtx {
86
184
  * satisfy its state machine. Set from `reasoningRequested(body)`.
87
185
  */
88
186
  reasoningRequested?: boolean;
187
+ /**
188
+ * Alias table from `buildResponsesToolAliases(request.tools)`: maps Claude's
189
+ * tool_use names back onto Codex's `{namespace, name}` and custom tools.
190
+ */
191
+ toolAliases?: ResponsesToolAliases;
89
192
  }
90
193
  /** Did the Responses request ask for reasoning output? */
91
194
  export declare function reasoningRequested(body: ResponsesRequest): boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"openaiResponses.d.ts","sourceRoot":"","sources":["../../src/proxy/openaiResponses.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"openaiResponses.d.ts","sourceRoot":"","sources":["../../src/proxy/openaiResponses.ts"],"names":[],"mappings":"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"}