@rynfar/meridian 1.60.0 → 1.61.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.
- package/README.md +2 -1
- package/dist/{cli-k1djafvr.js → cli-tbhba0cv.js} +666 -220
- package/dist/cli.js +1 -1
- package/dist/{profilePage-naychnb8.js → profilePage-gtazq15d.js} +9 -0
- package/dist/proxy/adapters/detect.d.ts.map +1 -1
- package/dist/proxy/adapters/jcode.d.ts +13 -0
- package/dist/proxy/adapters/jcode.d.ts.map +1 -0
- package/dist/proxy/errors.d.ts.map +1 -1
- package/dist/proxy/messages.d.ts +28 -0
- package/dist/proxy/messages.d.ts.map +1 -1
- package/dist/proxy/oauthUsage.d.ts +34 -1
- package/dist/proxy/oauthUsage.d.ts.map +1 -1
- package/dist/proxy/openai.d.ts +5 -1
- package/dist/proxy/openai.d.ts.map +1 -1
- package/dist/proxy/passthroughEarlyStop.d.ts +48 -0
- package/dist/proxy/passthroughEarlyStop.d.ts.map +1 -1
- package/dist/proxy/query.d.ts +3 -2
- package/dist/proxy/query.d.ts.map +1 -1
- package/dist/proxy/sdkFeatures.d.ts.map +1 -1
- package/dist/proxy/server.d.ts.map +1 -1
- package/dist/proxy/session/cache.d.ts +1 -1
- package/dist/proxy/session/cache.d.ts.map +1 -1
- package/dist/proxy/session/lineage.d.ts +12 -0
- package/dist/proxy/session/lineage.d.ts.map +1 -1
- package/dist/proxy/sessionStore.d.ts +5 -1
- package/dist/proxy/sessionStore.d.ts.map +1 -1
- package/dist/proxy/transforms/registry.d.ts.map +1 -1
- package/dist/proxy/turnOutcome.d.ts +179 -0
- package/dist/proxy/turnOutcome.d.ts.map +1 -0
- package/dist/server.js +1 -1
- package/dist/telemetry/profilePage.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -1752,6 +1752,133 @@ var init_sqlite = __esm(() => {
|
|
|
1752
1752
|
];
|
|
1753
1753
|
});
|
|
1754
1754
|
|
|
1755
|
+
// src/proxy/fileChanges.ts
|
|
1756
|
+
function extractFileChange(toolName, toolInput, mcpPrefix) {
|
|
1757
|
+
if (!toolName.startsWith(mcpPrefix))
|
|
1758
|
+
return;
|
|
1759
|
+
const shortName = toolName.slice(mcpPrefix.length);
|
|
1760
|
+
const input = toolInput;
|
|
1761
|
+
if (shortName === "write" && input?.path) {
|
|
1762
|
+
return { operation: "wrote", path: String(input.path) };
|
|
1763
|
+
}
|
|
1764
|
+
if (shortName === "edit" && input?.path) {
|
|
1765
|
+
return { operation: "edited", path: String(input.path) };
|
|
1766
|
+
}
|
|
1767
|
+
return;
|
|
1768
|
+
}
|
|
1769
|
+
function createFileChangeHook(changes, mcpPrefix) {
|
|
1770
|
+
return {
|
|
1771
|
+
matcher: "",
|
|
1772
|
+
hooks: [async (input) => {
|
|
1773
|
+
const change = extractFileChange(input.tool_name, input.tool_input, mcpPrefix);
|
|
1774
|
+
if (change) {
|
|
1775
|
+
changes.push(change);
|
|
1776
|
+
return {};
|
|
1777
|
+
}
|
|
1778
|
+
if (input.tool_name === `${mcpPrefix}bash`) {
|
|
1779
|
+
const toolInput = input.tool_input;
|
|
1780
|
+
if (toolInput?.command) {
|
|
1781
|
+
const bashChanges = extractFileChangesFromBash(String(toolInput.command));
|
|
1782
|
+
changes.push(...bashChanges);
|
|
1783
|
+
}
|
|
1784
|
+
}
|
|
1785
|
+
return {};
|
|
1786
|
+
}]
|
|
1787
|
+
};
|
|
1788
|
+
}
|
|
1789
|
+
function isLikelyFilePath(s) {
|
|
1790
|
+
if (s.length > 4096)
|
|
1791
|
+
return false;
|
|
1792
|
+
if (/[<>$`\\()[\]{}=]/.test(s))
|
|
1793
|
+
return false;
|
|
1794
|
+
if (/^-?\d+$/.test(s))
|
|
1795
|
+
return false;
|
|
1796
|
+
if (s.includes("/"))
|
|
1797
|
+
return true;
|
|
1798
|
+
if (/\.[A-Za-z0-9]{1,16}$/.test(s))
|
|
1799
|
+
return true;
|
|
1800
|
+
return false;
|
|
1801
|
+
}
|
|
1802
|
+
function extractFileChangesFromBash(command) {
|
|
1803
|
+
const changes = [];
|
|
1804
|
+
const seen = new Set;
|
|
1805
|
+
const addChange = (operation, path) => {
|
|
1806
|
+
if (path === "/dev/null" || path === "/dev/stderr" || path === "/dev/stdout")
|
|
1807
|
+
return;
|
|
1808
|
+
if (!path.trim())
|
|
1809
|
+
return;
|
|
1810
|
+
const key = `${operation}:${path}`;
|
|
1811
|
+
if (!seen.has(key)) {
|
|
1812
|
+
seen.add(key);
|
|
1813
|
+
changes.push({ operation, path });
|
|
1814
|
+
}
|
|
1815
|
+
};
|
|
1816
|
+
const redirectRegex = /(?<![0-9=])>{1,2}\s*['"]?([^\s'";&|)]+)['"]?/g;
|
|
1817
|
+
let match2;
|
|
1818
|
+
while ((match2 = redirectRegex.exec(command)) !== null) {
|
|
1819
|
+
if (isLikelyFilePath(match2[1])) {
|
|
1820
|
+
addChange("wrote", match2[1]);
|
|
1821
|
+
}
|
|
1822
|
+
}
|
|
1823
|
+
const teeRegex = /\btee\s+(?:-[a-zA-Z]\s+)*['"]?([^\s'";&|)]+)['"]?/g;
|
|
1824
|
+
while ((match2 = teeRegex.exec(command)) !== null) {
|
|
1825
|
+
addChange("wrote", match2[1]);
|
|
1826
|
+
}
|
|
1827
|
+
const sedRegex = /\bsed\s+(?:-[a-zA-Z]*i[a-zA-Z]*|-i)\b.*?['"]?([^\s'";&|)]+)['"]?\s*$/gm;
|
|
1828
|
+
while ((match2 = sedRegex.exec(command)) !== null) {
|
|
1829
|
+
addChange("edited", match2[1]);
|
|
1830
|
+
}
|
|
1831
|
+
return changes;
|
|
1832
|
+
}
|
|
1833
|
+
function extractFileChangesFromMessages(messages, extractFn) {
|
|
1834
|
+
const changes = [];
|
|
1835
|
+
const executedToolIds = new Set;
|
|
1836
|
+
for (const msg of messages) {
|
|
1837
|
+
if (msg.role !== "user")
|
|
1838
|
+
continue;
|
|
1839
|
+
const content = Array.isArray(msg.content) ? msg.content : [];
|
|
1840
|
+
for (const block of content) {
|
|
1841
|
+
if (block?.type === "tool_result" && block.tool_use_id) {
|
|
1842
|
+
executedToolIds.add(block.tool_use_id);
|
|
1843
|
+
}
|
|
1844
|
+
}
|
|
1845
|
+
}
|
|
1846
|
+
for (const msg of messages) {
|
|
1847
|
+
if (msg.role !== "assistant")
|
|
1848
|
+
continue;
|
|
1849
|
+
const content = Array.isArray(msg.content) ? msg.content : [];
|
|
1850
|
+
for (const block of content) {
|
|
1851
|
+
if (block?.type !== "tool_use")
|
|
1852
|
+
continue;
|
|
1853
|
+
if (!executedToolIds.has(block.id))
|
|
1854
|
+
continue;
|
|
1855
|
+
const blockChanges = extractFn(block.name, block.input);
|
|
1856
|
+
changes.push(...blockChanges);
|
|
1857
|
+
}
|
|
1858
|
+
}
|
|
1859
|
+
return changes;
|
|
1860
|
+
}
|
|
1861
|
+
function formatFileChangeSummary(changes) {
|
|
1862
|
+
if (changes.length === 0)
|
|
1863
|
+
return;
|
|
1864
|
+
const seen = new Set;
|
|
1865
|
+
const unique = [];
|
|
1866
|
+
for (const c of changes) {
|
|
1867
|
+
const key = `${c.operation}:${c.path}`;
|
|
1868
|
+
if (!seen.has(key)) {
|
|
1869
|
+
seen.add(key);
|
|
1870
|
+
unique.push(c);
|
|
1871
|
+
}
|
|
1872
|
+
}
|
|
1873
|
+
const lines = unique.map((c) => `- ${c.operation} ${c.path}`);
|
|
1874
|
+
return `
|
|
1875
|
+
|
|
1876
|
+
Files changed:
|
|
1877
|
+
${lines.join(`
|
|
1878
|
+
`)}`;
|
|
1879
|
+
}
|
|
1880
|
+
var init_fileChanges = () => {};
|
|
1881
|
+
|
|
1755
1882
|
// src/proxy/messages.ts
|
|
1756
1883
|
function stripCacheControlForHashing(obj) {
|
|
1757
1884
|
if (!obj || typeof obj !== "object")
|
|
@@ -1831,6 +1958,13 @@ ${history}
|
|
|
1831
1958
|
|
|
1832
1959
|
` + last.text;
|
|
1833
1960
|
}
|
|
1961
|
+
function framePassthroughContinuation(delta) {
|
|
1962
|
+
if (!delta)
|
|
1963
|
+
return delta;
|
|
1964
|
+
return `${PASSTHROUGH_CONTINUATION_LEAD_IN}
|
|
1965
|
+
|
|
1966
|
+
${delta}`;
|
|
1967
|
+
}
|
|
1834
1968
|
function stripNonStandardStreamFields(event) {
|
|
1835
1969
|
if (event && typeof event === "object") {
|
|
1836
1970
|
const e = event;
|
|
@@ -1957,7 +2091,7 @@ function extractSystemText(system) {
|
|
|
1957
2091
|
return system.filter((b) => b?.type === "text" && typeof b.text === "string" && b.text).map((b) => b.text).filter((text) => !TRANSPORT_HEADER_BLOCK.test(text)).join(`
|
|
1958
2092
|
`);
|
|
1959
2093
|
}
|
|
1960
|
-
var HASH_IGNORED_BLOCK_TYPES, HASH_HANDLED_BLOCK_TYPES, HASH_SERIALIZED_BLOCK_TYPES, MULTIMODAL_TYPES, TOOL_TARGET_KEYS, CONTENT_SUMMARY_MAX = 120, TRANSPORT_HEADER_BLOCK;
|
|
2094
|
+
var HASH_IGNORED_BLOCK_TYPES, HASH_HANDLED_BLOCK_TYPES, HASH_SERIALIZED_BLOCK_TYPES, PASSTHROUGH_CONTINUATION_LEAD_IN, MULTIMODAL_TYPES, TOOL_TARGET_KEYS, CONTENT_SUMMARY_MAX = 120, TRANSPORT_HEADER_BLOCK;
|
|
1961
2095
|
var init_messages = __esm(() => {
|
|
1962
2096
|
HASH_IGNORED_BLOCK_TYPES = new Set(["thinking", "redacted_thinking"]);
|
|
1963
2097
|
HASH_HANDLED_BLOCK_TYPES = new Set(["text", "tool_use", "tool_result"]);
|
|
@@ -1974,138 +2108,12 @@ var init_messages = __esm(() => {
|
|
|
1974
2108
|
"tool_search_tool_result",
|
|
1975
2109
|
"container_upload"
|
|
1976
2110
|
]);
|
|
2111
|
+
PASSTHROUGH_CONTINUATION_LEAD_IN = "The tool calls from your previous turn were forwarded to the client, which has now executed them — " + "their results follow. The instruction to end that turn without further text applied to it alone and " + "is now discharged: continue the work and respond.";
|
|
1977
2112
|
MULTIMODAL_TYPES = new Set(["image", "document", "file"]);
|
|
1978
2113
|
TOOL_TARGET_KEYS = ["filePath", "file_path", "path", "command", "pattern", "query", "url"];
|
|
1979
2114
|
TRANSPORT_HEADER_BLOCK = /^\s*x-anthropic-[a-z0-9-]*header\s*:/i;
|
|
1980
2115
|
});
|
|
1981
2116
|
|
|
1982
|
-
// src/proxy/fileChanges.ts
|
|
1983
|
-
function extractFileChange(toolName, toolInput, mcpPrefix) {
|
|
1984
|
-
if (!toolName.startsWith(mcpPrefix))
|
|
1985
|
-
return;
|
|
1986
|
-
const shortName = toolName.slice(mcpPrefix.length);
|
|
1987
|
-
const input = toolInput;
|
|
1988
|
-
if (shortName === "write" && input?.path) {
|
|
1989
|
-
return { operation: "wrote", path: String(input.path) };
|
|
1990
|
-
}
|
|
1991
|
-
if (shortName === "edit" && input?.path) {
|
|
1992
|
-
return { operation: "edited", path: String(input.path) };
|
|
1993
|
-
}
|
|
1994
|
-
return;
|
|
1995
|
-
}
|
|
1996
|
-
function createFileChangeHook(changes, mcpPrefix) {
|
|
1997
|
-
return {
|
|
1998
|
-
matcher: "",
|
|
1999
|
-
hooks: [async (input) => {
|
|
2000
|
-
const change = extractFileChange(input.tool_name, input.tool_input, mcpPrefix);
|
|
2001
|
-
if (change) {
|
|
2002
|
-
changes.push(change);
|
|
2003
|
-
return {};
|
|
2004
|
-
}
|
|
2005
|
-
if (input.tool_name === `${mcpPrefix}bash`) {
|
|
2006
|
-
const toolInput = input.tool_input;
|
|
2007
|
-
if (toolInput?.command) {
|
|
2008
|
-
const bashChanges = extractFileChangesFromBash(String(toolInput.command));
|
|
2009
|
-
changes.push(...bashChanges);
|
|
2010
|
-
}
|
|
2011
|
-
}
|
|
2012
|
-
return {};
|
|
2013
|
-
}]
|
|
2014
|
-
};
|
|
2015
|
-
}
|
|
2016
|
-
function isLikelyFilePath(s) {
|
|
2017
|
-
if (s.length > 4096)
|
|
2018
|
-
return false;
|
|
2019
|
-
if (/[<>$`\\()[\]{}=]/.test(s))
|
|
2020
|
-
return false;
|
|
2021
|
-
if (/^-?\d+$/.test(s))
|
|
2022
|
-
return false;
|
|
2023
|
-
if (s.includes("/"))
|
|
2024
|
-
return true;
|
|
2025
|
-
if (/\.[A-Za-z0-9]{1,16}$/.test(s))
|
|
2026
|
-
return true;
|
|
2027
|
-
return false;
|
|
2028
|
-
}
|
|
2029
|
-
function extractFileChangesFromBash(command) {
|
|
2030
|
-
const changes = [];
|
|
2031
|
-
const seen = new Set;
|
|
2032
|
-
const addChange = (operation, path) => {
|
|
2033
|
-
if (path === "/dev/null" || path === "/dev/stderr" || path === "/dev/stdout")
|
|
2034
|
-
return;
|
|
2035
|
-
if (!path.trim())
|
|
2036
|
-
return;
|
|
2037
|
-
const key = `${operation}:${path}`;
|
|
2038
|
-
if (!seen.has(key)) {
|
|
2039
|
-
seen.add(key);
|
|
2040
|
-
changes.push({ operation, path });
|
|
2041
|
-
}
|
|
2042
|
-
};
|
|
2043
|
-
const redirectRegex = /(?<![0-9=])>{1,2}\s*['"]?([^\s'";&|)]+)['"]?/g;
|
|
2044
|
-
let match2;
|
|
2045
|
-
while ((match2 = redirectRegex.exec(command)) !== null) {
|
|
2046
|
-
if (isLikelyFilePath(match2[1])) {
|
|
2047
|
-
addChange("wrote", match2[1]);
|
|
2048
|
-
}
|
|
2049
|
-
}
|
|
2050
|
-
const teeRegex = /\btee\s+(?:-[a-zA-Z]\s+)*['"]?([^\s'";&|)]+)['"]?/g;
|
|
2051
|
-
while ((match2 = teeRegex.exec(command)) !== null) {
|
|
2052
|
-
addChange("wrote", match2[1]);
|
|
2053
|
-
}
|
|
2054
|
-
const sedRegex = /\bsed\s+(?:-[a-zA-Z]*i[a-zA-Z]*|-i)\b.*?['"]?([^\s'";&|)]+)['"]?\s*$/gm;
|
|
2055
|
-
while ((match2 = sedRegex.exec(command)) !== null) {
|
|
2056
|
-
addChange("edited", match2[1]);
|
|
2057
|
-
}
|
|
2058
|
-
return changes;
|
|
2059
|
-
}
|
|
2060
|
-
function extractFileChangesFromMessages(messages, extractFn) {
|
|
2061
|
-
const changes = [];
|
|
2062
|
-
const executedToolIds = new Set;
|
|
2063
|
-
for (const msg of messages) {
|
|
2064
|
-
if (msg.role !== "user")
|
|
2065
|
-
continue;
|
|
2066
|
-
const content = Array.isArray(msg.content) ? msg.content : [];
|
|
2067
|
-
for (const block of content) {
|
|
2068
|
-
if (block?.type === "tool_result" && block.tool_use_id) {
|
|
2069
|
-
executedToolIds.add(block.tool_use_id);
|
|
2070
|
-
}
|
|
2071
|
-
}
|
|
2072
|
-
}
|
|
2073
|
-
for (const msg of messages) {
|
|
2074
|
-
if (msg.role !== "assistant")
|
|
2075
|
-
continue;
|
|
2076
|
-
const content = Array.isArray(msg.content) ? msg.content : [];
|
|
2077
|
-
for (const block of content) {
|
|
2078
|
-
if (block?.type !== "tool_use")
|
|
2079
|
-
continue;
|
|
2080
|
-
if (!executedToolIds.has(block.id))
|
|
2081
|
-
continue;
|
|
2082
|
-
const blockChanges = extractFn(block.name, block.input);
|
|
2083
|
-
changes.push(...blockChanges);
|
|
2084
|
-
}
|
|
2085
|
-
}
|
|
2086
|
-
return changes;
|
|
2087
|
-
}
|
|
2088
|
-
function formatFileChangeSummary(changes) {
|
|
2089
|
-
if (changes.length === 0)
|
|
2090
|
-
return;
|
|
2091
|
-
const seen = new Set;
|
|
2092
|
-
const unique = [];
|
|
2093
|
-
for (const c of changes) {
|
|
2094
|
-
const key = `${c.operation}:${c.path}`;
|
|
2095
|
-
if (!seen.has(key)) {
|
|
2096
|
-
seen.add(key);
|
|
2097
|
-
unique.push(c);
|
|
2098
|
-
}
|
|
2099
|
-
}
|
|
2100
|
-
const lines = unique.map((c) => `- ${c.operation} ${c.path}`);
|
|
2101
|
-
return `
|
|
2102
|
-
|
|
2103
|
-
Files changed:
|
|
2104
|
-
${lines.join(`
|
|
2105
|
-
`)}`;
|
|
2106
|
-
}
|
|
2107
|
-
var init_fileChanges = () => {};
|
|
2108
|
-
|
|
2109
2117
|
// src/proxy/session/fingerprint.ts
|
|
2110
2118
|
import { createHash } from "crypto";
|
|
2111
2119
|
function extractClientCwd(body) {
|
|
@@ -2151,7 +2159,7 @@ var init_opencode = __esm(() => {
|
|
|
2151
2159
|
openCodeTransforms = [
|
|
2152
2160
|
{
|
|
2153
2161
|
name: "opencode-core",
|
|
2154
|
-
adapters: ["opencode", "openai", "codex"],
|
|
2162
|
+
adapters: ["opencode", "openai", "jcode", "codex"],
|
|
2155
2163
|
onRequest(ctx) {
|
|
2156
2164
|
const body = ctx.body;
|
|
2157
2165
|
const blockedTools = BLOCKED_BUILTIN_TOOLS;
|
|
@@ -2325,6 +2333,51 @@ IMPORTANT: When using the task/Task tool, the subagent_type parameter must be on
|
|
|
2325
2333
|
};
|
|
2326
2334
|
});
|
|
2327
2335
|
|
|
2336
|
+
// src/proxy/adapters/openai.ts
|
|
2337
|
+
var openAiAdapter;
|
|
2338
|
+
var init_openai = __esm(() => {
|
|
2339
|
+
init_opencode2();
|
|
2340
|
+
openAiAdapter = {
|
|
2341
|
+
...openCodeAdapter,
|
|
2342
|
+
name: "openai"
|
|
2343
|
+
};
|
|
2344
|
+
});
|
|
2345
|
+
|
|
2346
|
+
// src/proxy/adapters/jcode.ts
|
|
2347
|
+
function normalizeJcodeSessionId(value) {
|
|
2348
|
+
const trimmed = value?.trim();
|
|
2349
|
+
return trimmed && JCODE_SESSION_ID.test(trimmed) ? trimmed : undefined;
|
|
2350
|
+
}
|
|
2351
|
+
function isTextSystemBlock(value) {
|
|
2352
|
+
if (value === null || typeof value !== "object")
|
|
2353
|
+
return false;
|
|
2354
|
+
const part = value;
|
|
2355
|
+
return part.type === "text" && typeof part.text === "string";
|
|
2356
|
+
}
|
|
2357
|
+
function extractJcodeWorkingDirectory(body) {
|
|
2358
|
+
if (body === null || typeof body !== "object")
|
|
2359
|
+
return;
|
|
2360
|
+
const system = body.system;
|
|
2361
|
+
const text = typeof system === "string" ? system : Array.isArray(system) ? system.filter(isTextSystemBlock).map((part) => part.text).join(`
|
|
2362
|
+
`) : "";
|
|
2363
|
+
return text.match(/(?:^|\n)Working directory:[^\S\n]*([^\n]+)/)?.[1]?.trim() || undefined;
|
|
2364
|
+
}
|
|
2365
|
+
var JCODE_SESSION_ID, jcodeAdapter;
|
|
2366
|
+
var init_jcode = __esm(() => {
|
|
2367
|
+
init_openai();
|
|
2368
|
+
JCODE_SESSION_ID = /^[A-Za-z0-9._:-]{1,256}$/;
|
|
2369
|
+
jcodeAdapter = {
|
|
2370
|
+
...openAiAdapter,
|
|
2371
|
+
name: "jcode",
|
|
2372
|
+
getSessionId(c) {
|
|
2373
|
+
return normalizeJcodeSessionId(c.req.header("x-jcode-session"));
|
|
2374
|
+
},
|
|
2375
|
+
extractWorkingDirectory(body) {
|
|
2376
|
+
return extractJcodeWorkingDirectory(body);
|
|
2377
|
+
}
|
|
2378
|
+
};
|
|
2379
|
+
});
|
|
2380
|
+
|
|
2328
2381
|
// src/proxy/transforms/droid.ts
|
|
2329
2382
|
function resolveDroidPassthrough() {
|
|
2330
2383
|
return resolvePassthrough(false);
|
|
@@ -3008,16 +3061,6 @@ var init_forgecode2 = __esm(() => {
|
|
|
3008
3061
|
};
|
|
3009
3062
|
});
|
|
3010
3063
|
|
|
3011
|
-
// src/proxy/adapters/openai.ts
|
|
3012
|
-
var openAiAdapter;
|
|
3013
|
-
var init_openai = __esm(() => {
|
|
3014
|
-
init_opencode2();
|
|
3015
|
-
openAiAdapter = {
|
|
3016
|
-
...openCodeAdapter,
|
|
3017
|
-
name: "openai"
|
|
3018
|
-
};
|
|
3019
|
-
});
|
|
3020
|
-
|
|
3021
3064
|
// src/proxy/adapters/codex.ts
|
|
3022
3065
|
var codexAdapter;
|
|
3023
3066
|
var init_codex = __esm(() => {
|
|
@@ -3202,6 +3245,9 @@ function detectAdapter(c) {
|
|
|
3202
3245
|
return openCodeAdapter;
|
|
3203
3246
|
}
|
|
3204
3247
|
const userAgent = c.req.header("user-agent") || "";
|
|
3248
|
+
if (userAgent.startsWith("jcode/") && normalizeJcodeSessionId(c.req.header("x-jcode-session"))) {
|
|
3249
|
+
return jcodeAdapter;
|
|
3250
|
+
}
|
|
3205
3251
|
if (userAgent.startsWith("opencode/")) {
|
|
3206
3252
|
return openCodeAdapter;
|
|
3207
3253
|
}
|
|
@@ -3236,6 +3282,7 @@ var init_detect = __esm(() => {
|
|
|
3236
3282
|
init_forgecode2();
|
|
3237
3283
|
init_claudecode();
|
|
3238
3284
|
init_openai();
|
|
3285
|
+
init_jcode();
|
|
3239
3286
|
init_codex();
|
|
3240
3287
|
init_cherry();
|
|
3241
3288
|
init_adapterInstances();
|
|
@@ -3251,6 +3298,7 @@ var init_detect = __esm(() => {
|
|
|
3251
3298
|
cherry: cherryAdapter,
|
|
3252
3299
|
cherrystudio: cherryAdapter,
|
|
3253
3300
|
openai: openAiAdapter,
|
|
3301
|
+
jcode: jcodeAdapter,
|
|
3254
3302
|
codex: codexAdapter
|
|
3255
3303
|
};
|
|
3256
3304
|
envDefault = process.env.MERIDIAN_DEFAULT_AGENT || "";
|
|
@@ -3401,6 +3449,9 @@ var init_sdkFeatures = __esm(() => {
|
|
|
3401
3449
|
openai: {
|
|
3402
3450
|
codeSystemPrompt: false
|
|
3403
3451
|
},
|
|
3452
|
+
jcode: {
|
|
3453
|
+
codeSystemPrompt: false
|
|
3454
|
+
},
|
|
3404
3455
|
cherry: {
|
|
3405
3456
|
codeSystemPrompt: false
|
|
3406
3457
|
},
|
|
@@ -6294,8 +6345,10 @@ var OAUTH_USAGE_URL = "https://api.anthropic.com/api/oauth/usage";
|
|
|
6294
6345
|
var OAUTH_BETA_HEADER = "oauth-2025-04-20";
|
|
6295
6346
|
var CACHE_TTL_MS_DEFAULT = 30000;
|
|
6296
6347
|
var STALE_MAX_MS_DEFAULT = 15 * 60000;
|
|
6348
|
+
var RATE_LIMIT_BACKOFF_MS_DEFAULT = 60000;
|
|
6297
6349
|
var cacheByProfile = new Map;
|
|
6298
6350
|
var inflightByProfile = new Map;
|
|
6351
|
+
var rateLimitedUntilByProfile = new Map;
|
|
6299
6352
|
var DEFAULT_KEY = "__default__";
|
|
6300
6353
|
var WINDOW_TYPES = [
|
|
6301
6354
|
"five_hour",
|
|
@@ -6317,6 +6370,15 @@ function normalizeUtilization(raw2) {
|
|
|
6317
6370
|
return null;
|
|
6318
6371
|
return Math.max(0, raw2 / 100);
|
|
6319
6372
|
}
|
|
6373
|
+
function parseRetryAfterMs(raw2) {
|
|
6374
|
+
if (!raw2)
|
|
6375
|
+
return null;
|
|
6376
|
+
const seconds = Number(raw2);
|
|
6377
|
+
if (Number.isFinite(seconds))
|
|
6378
|
+
return Math.max(0, seconds * 1000);
|
|
6379
|
+
const retryAt = Date.parse(raw2);
|
|
6380
|
+
return Number.isFinite(retryAt) ? Math.max(0, retryAt - Date.now()) : null;
|
|
6381
|
+
}
|
|
6320
6382
|
function modelScopedWindowType(limit) {
|
|
6321
6383
|
if (limit.kind !== "weekly_scoped")
|
|
6322
6384
|
return null;
|
|
@@ -6374,14 +6436,27 @@ async function callAnthropic(token, fetchImpl, signal) {
|
|
|
6374
6436
|
},
|
|
6375
6437
|
signal: signal ?? AbortSignal.timeout(1e4)
|
|
6376
6438
|
});
|
|
6377
|
-
if (!res.ok)
|
|
6378
|
-
return {
|
|
6439
|
+
if (!res.ok) {
|
|
6440
|
+
return {
|
|
6441
|
+
__status: res.status,
|
|
6442
|
+
retryAfterMs: parseRetryAfterMs(res.headers.get("retry-after"))
|
|
6443
|
+
};
|
|
6444
|
+
}
|
|
6379
6445
|
return await res.json();
|
|
6380
6446
|
}
|
|
6381
6447
|
var _testOverride = null;
|
|
6382
6448
|
async function fetchOAuthUsage(opts) {
|
|
6449
|
+
return (await fetchOAuthUsageResult(opts)).snapshot;
|
|
6450
|
+
}
|
|
6451
|
+
function missingReason(cacheKey2) {
|
|
6452
|
+
const until = rateLimitedUntilByProfile.get(cacheKey2);
|
|
6453
|
+
return until !== undefined && Date.now() < until ? "rate_limited" : "no_token";
|
|
6454
|
+
}
|
|
6455
|
+
async function fetchOAuthUsageResult(opts) {
|
|
6383
6456
|
if (_testOverride && !opts?.fetchImpl && !opts?.store) {
|
|
6384
|
-
|
|
6457
|
+
const snapshot = await _testOverride(opts);
|
|
6458
|
+
const error = snapshot ? null : missingReason(opts?.profileId ?? DEFAULT_KEY);
|
|
6459
|
+
return { snapshot, error };
|
|
6385
6460
|
}
|
|
6386
6461
|
return fetchOAuthUsageImpl(opts);
|
|
6387
6462
|
}
|
|
@@ -6389,30 +6464,37 @@ async function fetchOAuthUsageImpl(opts) {
|
|
|
6389
6464
|
const ttl = opts?.ttlMs ?? CACHE_TTL_MS_DEFAULT;
|
|
6390
6465
|
const cacheKey2 = opts?.profileId ?? DEFAULT_KEY;
|
|
6391
6466
|
const fetchImpl = opts?.fetchImpl ?? globalThis.fetch;
|
|
6467
|
+
const staleMaxMs = opts?.staleMaxMs ?? STALE_MAX_MS_DEFAULT;
|
|
6468
|
+
const staleOr = (reason, error) => {
|
|
6469
|
+
const last = cacheByProfile.get(cacheKey2);
|
|
6470
|
+
if (last && Date.now() - last.fetchedAt < staleMaxMs) {
|
|
6471
|
+
claudeLog("oauth_usage.serving_stale", { profile: cacheKey2, reason, ageMs: Date.now() - last.fetchedAt });
|
|
6472
|
+
return { snapshot: { ...last, stale: true }, error: null };
|
|
6473
|
+
}
|
|
6474
|
+
return { snapshot: null, error };
|
|
6475
|
+
};
|
|
6392
6476
|
if (!opts?.force) {
|
|
6393
6477
|
const cached = cacheByProfile.get(cacheKey2);
|
|
6394
6478
|
if (cached && Date.now() - cached.fetchedAt < ttl)
|
|
6395
|
-
return cached;
|
|
6479
|
+
return { snapshot: cached, error: null };
|
|
6396
6480
|
}
|
|
6397
6481
|
const existing = inflightByProfile.get(cacheKey2);
|
|
6398
6482
|
if (existing)
|
|
6399
6483
|
return existing;
|
|
6484
|
+
const rateLimitedUntil = rateLimitedUntilByProfile.get(cacheKey2);
|
|
6485
|
+
if (rateLimitedUntil !== undefined) {
|
|
6486
|
+
if (Date.now() < rateLimitedUntil)
|
|
6487
|
+
return staleOr("rate_limited", "rate_limited");
|
|
6488
|
+
rateLimitedUntilByProfile.delete(cacheKey2);
|
|
6489
|
+
}
|
|
6400
6490
|
const store = opts?.store ?? createPlatformCredentialStore({ claudeConfigDir: opts?.claudeConfigDir });
|
|
6401
|
-
const
|
|
6402
|
-
const staleOr = (reason) => {
|
|
6403
|
-
const last = cacheByProfile.get(cacheKey2);
|
|
6404
|
-
if (last && Date.now() - last.fetchedAt < staleMaxMs) {
|
|
6405
|
-
claudeLog("oauth_usage.serving_stale", { profile: cacheKey2, reason, ageMs: Date.now() - last.fetchedAt });
|
|
6406
|
-
return { ...last, stale: true };
|
|
6407
|
-
}
|
|
6408
|
-
return null;
|
|
6409
|
-
};
|
|
6491
|
+
const rateLimitBackoffMs = opts?.rateLimitBackoffMs ?? RATE_LIMIT_BACKOFF_MS_DEFAULT;
|
|
6410
6492
|
const promise = (async () => {
|
|
6411
6493
|
try {
|
|
6412
6494
|
const token = await readAccessToken(store);
|
|
6413
6495
|
if (!token) {
|
|
6414
6496
|
claudeLog("oauth_usage.no_token", { profile: cacheKey2 });
|
|
6415
|
-
return staleOr("no_token");
|
|
6497
|
+
return staleOr("no_token", "no_token");
|
|
6416
6498
|
}
|
|
6417
6499
|
let result = await callAnthropic(token, fetchImpl);
|
|
6418
6500
|
if ("__status" in result && result.__status === 401) {
|
|
@@ -6420,23 +6502,28 @@ async function fetchOAuthUsageImpl(opts) {
|
|
|
6420
6502
|
const refreshed = await refreshOAuthToken(store);
|
|
6421
6503
|
if (!refreshed) {
|
|
6422
6504
|
claudeLog("oauth_usage.refresh_failed", { profile: cacheKey2 });
|
|
6423
|
-
return staleOr("refresh_failed");
|
|
6505
|
+
return staleOr("refresh_failed", "upstream_error");
|
|
6424
6506
|
}
|
|
6425
6507
|
const newToken = await readAccessToken(store);
|
|
6426
6508
|
if (!newToken)
|
|
6427
|
-
return staleOr("no_token_after_refresh");
|
|
6509
|
+
return staleOr("no_token_after_refresh", "no_token");
|
|
6428
6510
|
result = await callAnthropic(newToken, fetchImpl);
|
|
6429
6511
|
}
|
|
6430
6512
|
if ("__status" in result) {
|
|
6513
|
+
if (result.__status === 429) {
|
|
6514
|
+
const retryAfterMs = Math.min(Math.max(rateLimitBackoffMs, result.retryAfterMs ?? 0), Math.max(staleMaxMs, rateLimitBackoffMs));
|
|
6515
|
+
rateLimitedUntilByProfile.set(cacheKey2, Date.now() + retryAfterMs);
|
|
6516
|
+
}
|
|
6431
6517
|
claudeLog("oauth_usage.upstream_error", { profile: cacheKey2, status: result.__status });
|
|
6432
|
-
return staleOr(`upstream_${result.__status}
|
|
6518
|
+
return staleOr(`upstream_${result.__status}`, result.__status === 429 ? "rate_limited" : "upstream_error");
|
|
6433
6519
|
}
|
|
6520
|
+
rateLimitedUntilByProfile.delete(cacheKey2);
|
|
6434
6521
|
const snapshot = buildSnapshot(result);
|
|
6435
6522
|
cacheByProfile.set(cacheKey2, snapshot);
|
|
6436
|
-
return snapshot;
|
|
6523
|
+
return { snapshot, error: null };
|
|
6437
6524
|
} catch (err) {
|
|
6438
6525
|
claudeLog("oauth_usage.fetch_failed", { profile: cacheKey2, error: err instanceof Error ? err.message : String(err) });
|
|
6439
|
-
return staleOr("exception");
|
|
6526
|
+
return staleOr("exception", "upstream_error");
|
|
6440
6527
|
} finally {
|
|
6441
6528
|
inflightByProfile.delete(cacheKey2);
|
|
6442
6529
|
}
|
|
@@ -10715,6 +10802,31 @@ function shouldEarlyStop(tracker) {
|
|
|
10715
10802
|
tracker.fired = true;
|
|
10716
10803
|
return true;
|
|
10717
10804
|
}
|
|
10805
|
+
function clientAbortDisposition(input) {
|
|
10806
|
+
if (input.isIndependentSession || !input.profileSessionId)
|
|
10807
|
+
return { action: "none" };
|
|
10808
|
+
if (!input.passthrough)
|
|
10809
|
+
return { action: "evict" };
|
|
10810
|
+
if (input.currentSessionId && !input.sawDuplicateToolUse && input.resumeBoundaryUuid) {
|
|
10811
|
+
return { action: "store", resumeUuid: input.resumeBoundaryUuid };
|
|
10812
|
+
}
|
|
10813
|
+
return { action: "evict" };
|
|
10814
|
+
}
|
|
10815
|
+
function resumeBoundaryUuid(message) {
|
|
10816
|
+
const m = message;
|
|
10817
|
+
if (m?.type !== "user")
|
|
10818
|
+
return;
|
|
10819
|
+
if (typeof m.uuid !== "string" || m.uuid.length === 0)
|
|
10820
|
+
return;
|
|
10821
|
+
const content = m.message?.content;
|
|
10822
|
+
if (!Array.isArray(content))
|
|
10823
|
+
return;
|
|
10824
|
+
const hasResult = content.some((block) => {
|
|
10825
|
+
const b = block;
|
|
10826
|
+
return b?.type === "tool_result";
|
|
10827
|
+
});
|
|
10828
|
+
return hasResult ? m.uuid : undefined;
|
|
10829
|
+
}
|
|
10718
10830
|
|
|
10719
10831
|
// src/proxy/envelopeIntegrity.ts
|
|
10720
10832
|
function checkEmptyToolInputs(contentBlocks, tools) {
|
|
@@ -10755,6 +10867,68 @@ function checkUndeliveredToolUses(captured, deliveredIds) {
|
|
|
10755
10867
|
return violations;
|
|
10756
10868
|
}
|
|
10757
10869
|
|
|
10870
|
+
// src/proxy/turnOutcome.ts
|
|
10871
|
+
function classifyTurnOutcome(input) {
|
|
10872
|
+
if (input.toolUses > 0)
|
|
10873
|
+
return { kind: "productive" };
|
|
10874
|
+
if (input.textEvents > 0)
|
|
10875
|
+
return { kind: "productive" };
|
|
10876
|
+
return {
|
|
10877
|
+
kind: "silent",
|
|
10878
|
+
reason: input.blocksForwarded > 0 ? "no_actionable_content" : "no_blocks"
|
|
10879
|
+
};
|
|
10880
|
+
}
|
|
10881
|
+
var SILENT_TURN_NUDGE = "Your previous turn produced no visible output — no text and no tool call — so the client received " + "nothing to act on. Any earlier instruction to end your turn without further text applied only to " + "that turn and is now discharged. Answer now, in text, addressing the most recent request and any " + "tool results above it. If a tool call is still required, make it.";
|
|
10882
|
+
function shouldInjectSilentTurn(input) {
|
|
10883
|
+
if (!input.raw)
|
|
10884
|
+
return false;
|
|
10885
|
+
if (input.raw === "1")
|
|
10886
|
+
return true;
|
|
10887
|
+
return Boolean(input.sessionId && input.raw === input.sessionId);
|
|
10888
|
+
}
|
|
10889
|
+
function createRecoveryLifter(allocateBlockIndex) {
|
|
10890
|
+
let blockIndex;
|
|
10891
|
+
return {
|
|
10892
|
+
lift(innerEvent) {
|
|
10893
|
+
const inner = innerEvent;
|
|
10894
|
+
if (!inner)
|
|
10895
|
+
return;
|
|
10896
|
+
if (inner.type === "content_block_start" && inner.content_block?.type === "text") {
|
|
10897
|
+
blockIndex = allocateBlockIndex();
|
|
10898
|
+
return {
|
|
10899
|
+
kind: "block_start",
|
|
10900
|
+
frame: { type: "content_block_start", index: blockIndex, content_block: { type: "text", text: "" } }
|
|
10901
|
+
};
|
|
10902
|
+
}
|
|
10903
|
+
if (inner.type === "content_block_delta" && inner.delta?.type === "text_delta" && blockIndex !== undefined) {
|
|
10904
|
+
const text = inner.delta.text;
|
|
10905
|
+
return {
|
|
10906
|
+
kind: "text_delta",
|
|
10907
|
+
frame: { type: "content_block_delta", index: blockIndex, delta: { type: "text_delta", text } },
|
|
10908
|
+
textChars: typeof text === "string" ? text.length : 0
|
|
10909
|
+
};
|
|
10910
|
+
}
|
|
10911
|
+
if (inner.type === "content_block_stop" && blockIndex !== undefined) {
|
|
10912
|
+
const index = blockIndex;
|
|
10913
|
+
blockIndex = undefined;
|
|
10914
|
+
return { kind: "block_stop", frame: { type: "content_block_stop", index } };
|
|
10915
|
+
}
|
|
10916
|
+
return;
|
|
10917
|
+
}
|
|
10918
|
+
};
|
|
10919
|
+
}
|
|
10920
|
+
function shouldAttemptRecovery(input) {
|
|
10921
|
+
if (!input.enabled)
|
|
10922
|
+
return false;
|
|
10923
|
+
if (input.outcome.kind === "productive")
|
|
10924
|
+
return false;
|
|
10925
|
+
if (input.alreadyAttempted)
|
|
10926
|
+
return false;
|
|
10927
|
+
if (input.clientGone)
|
|
10928
|
+
return false;
|
|
10929
|
+
return Boolean(input.sessionId);
|
|
10930
|
+
}
|
|
10931
|
+
|
|
10758
10932
|
// src/proxy/server.ts
|
|
10759
10933
|
init_agentMatch();
|
|
10760
10934
|
|
|
@@ -11780,6 +11954,7 @@ function extendedContextHint(model) {
|
|
|
11780
11954
|
return advise("MERIDIAN_SONNET_MODEL=sonnet");
|
|
11781
11955
|
return advise("MERIDIAN_1M_CONTEXT_SUPPORT=0");
|
|
11782
11956
|
}
|
|
11957
|
+
var HIT_YOUR_LIMIT = /hit your (?:[\w-]+ )?limit/;
|
|
11783
11958
|
function classifyError(errMsg, model) {
|
|
11784
11959
|
const lower = errMsg.toLowerCase();
|
|
11785
11960
|
if (lower.includes("oauth token has expired") || lower.includes("not logged in")) {
|
|
@@ -11796,7 +11971,7 @@ function classifyError(errMsg, model) {
|
|
|
11796
11971
|
message: "Claude authentication expired or invalid. Run 'claude login' in your terminal to re-authenticate, then restart the proxy."
|
|
11797
11972
|
};
|
|
11798
11973
|
}
|
|
11799
|
-
if (lower.includes("429") || lower.includes("rate limit") || lower.includes("too many requests") ||
|
|
11974
|
+
if (lower.includes("429") || lower.includes("rate limit") || lower.includes("too many requests") || HIT_YOUR_LIMIT.test(lower) || lower.includes("usage limit reached")) {
|
|
11800
11975
|
const hint = lower.includes("1m") || lower.includes("context") ? extendedContextHint(model) : "";
|
|
11801
11976
|
return {
|
|
11802
11977
|
status: 429,
|
|
@@ -12279,7 +12454,7 @@ ${c.text}
|
|
|
12279
12454
|
return "";
|
|
12280
12455
|
}).filter(Boolean).join("");
|
|
12281
12456
|
}
|
|
12282
|
-
function translateOpenAiToAnthropic(body) {
|
|
12457
|
+
function translateOpenAiToAnthropic(body, options = {}) {
|
|
12283
12458
|
const messages = body.messages ?? [];
|
|
12284
12459
|
if (messages.length === 0)
|
|
12285
12460
|
return null;
|
|
@@ -12371,7 +12546,7 @@ function translateOpenAiToAnthropic(body) {
|
|
|
12371
12546
|
let systemPrompt = systemParts.join(`
|
|
12372
12547
|
`);
|
|
12373
12548
|
let messagesToSend = turns;
|
|
12374
|
-
if (turns.length > 1) {
|
|
12549
|
+
if (turns.length > 1 && !options.preserveConversationHistory) {
|
|
12375
12550
|
const history = turns.slice(0, -1).map((m) => `${m.role}: ${summarizeAnthropicContent(m.content)}`).join(`
|
|
12376
12551
|
`);
|
|
12377
12552
|
const historyBlock = `<conversation_history>
|
|
@@ -12666,6 +12841,9 @@ function buildModelList(isMaxSubscription, now = Math.floor(Date.now() / 1000))
|
|
|
12666
12841
|
];
|
|
12667
12842
|
}
|
|
12668
12843
|
|
|
12844
|
+
// src/proxy/server.ts
|
|
12845
|
+
init_jcode();
|
|
12846
|
+
|
|
12669
12847
|
// src/proxy/openaiResponses.ts
|
|
12670
12848
|
function itemDiscriminator(item) {
|
|
12671
12849
|
if (typeof item !== "object" || item === null)
|
|
@@ -18858,7 +19036,7 @@ function buildQueryOptions(ctx, abortController) {
|
|
|
18858
19036
|
hasDeferredTools,
|
|
18859
19037
|
resumeSessionId,
|
|
18860
19038
|
isUndo,
|
|
18861
|
-
|
|
19039
|
+
resumeSessionAtUuid,
|
|
18862
19040
|
forkSession,
|
|
18863
19041
|
sdkHooks,
|
|
18864
19042
|
blockedTools,
|
|
@@ -18929,7 +19107,7 @@ function buildQueryOptions(ctx, abortController) {
|
|
|
18929
19107
|
...Object.keys(sdkAgents).length > 0 ? { agents: sdkAgents } : {},
|
|
18930
19108
|
...resumeSessionId ? { resume: resumeSessionId } : {},
|
|
18931
19109
|
...isUndo || forkSession ? { forkSession: true } : {},
|
|
18932
|
-
...
|
|
19110
|
+
...resumeSessionAtUuid ? { resumeSessionAt: resumeSessionAtUuid } : {},
|
|
18933
19111
|
...sdkHooks ? { hooks: sdkHooks } : {},
|
|
18934
19112
|
...effort ? { effort } : {},
|
|
18935
19113
|
...thinking ? { thinking } : {},
|
|
@@ -19076,6 +19254,7 @@ var ADAPTER_TRANSFORMS = {
|
|
|
19076
19254
|
cherry: cherryTransforms,
|
|
19077
19255
|
"claude-code": claudeCodeTransforms,
|
|
19078
19256
|
openai: openCodeTransforms,
|
|
19257
|
+
jcode: openCodeTransforms,
|
|
19079
19258
|
codex: [...openCodeTransforms, ...codexTransforms]
|
|
19080
19259
|
};
|
|
19081
19260
|
function getAdapterTransforms(adapterName) {
|
|
@@ -19088,7 +19267,7 @@ import { join as join5, isAbsolute as isAbsolute2, extname } from "path";
|
|
|
19088
19267
|
import { pathToFileURL } from "url";
|
|
19089
19268
|
|
|
19090
19269
|
// src/proxy/plugins/validation.ts
|
|
19091
|
-
var KNOWN_ADAPTERS = ["opencode", "openai", "crush", "droid", "pi", "forgecode", "passthrough"];
|
|
19270
|
+
var KNOWN_ADAPTERS = ["opencode", "openai", "jcode", "crush", "droid", "pi", "forgecode", "passthrough"];
|
|
19092
19271
|
var KNOWN_HOOKS = ["onRequest", "onResponse", "onTelemetry", "onSession", "onToolUse", "onToolResult", "onError"];
|
|
19093
19272
|
function validateTransform(exported) {
|
|
19094
19273
|
if (exported == null || typeof exported !== "object") {
|
|
@@ -19448,6 +19627,19 @@ function computeMessageHashes(messages) {
|
|
|
19448
19627
|
return [];
|
|
19449
19628
|
return messages.map(hashMessage);
|
|
19450
19629
|
}
|
|
19630
|
+
function hashNormalizedContent(content) {
|
|
19631
|
+
return createHash2("sha256").update(normalizeContent(content)).digest("hex").slice(0, 32);
|
|
19632
|
+
}
|
|
19633
|
+
function hashableContentBlocks(content) {
|
|
19634
|
+
if (!Array.isArray(content))
|
|
19635
|
+
return [content];
|
|
19636
|
+
return content.filter((block) => !HASH_IGNORED_BLOCK_TYPES.has(block?.type));
|
|
19637
|
+
}
|
|
19638
|
+
function computeMessageBlockHashes(messages) {
|
|
19639
|
+
if (!messages || messages.length === 0)
|
|
19640
|
+
return [];
|
|
19641
|
+
return messages.map((message) => hashableContentBlocks(message.content).map((block) => hashNormalizedContent(Array.isArray(message.content) ? [block] : block)));
|
|
19642
|
+
}
|
|
19451
19643
|
function measurePrefixOverlap(storedHashes, incomingHashes) {
|
|
19452
19644
|
let overlap = 0;
|
|
19453
19645
|
const minLen = Math.min(storedHashes.length, incomingHashes.length);
|
|
@@ -19530,6 +19722,34 @@ function verifyLineage(cached, messages) {
|
|
|
19530
19722
|
suffixOverlap
|
|
19531
19723
|
};
|
|
19532
19724
|
}
|
|
19725
|
+
const boundary = cached.messageCount - 1;
|
|
19726
|
+
if (boundary >= 0 && prefixOverlap === boundary && messages.length >= cached.messageCount && cached.messageBlockHashes?.length === cached.messageCount) {
|
|
19727
|
+
const incomingBoundary = messages[boundary];
|
|
19728
|
+
const storedBlocks = cached.messageBlockHashes[boundary];
|
|
19729
|
+
if (incomingBoundary?.role === "user" && storedBlocks && Array.isArray(incomingBoundary.content)) {
|
|
19730
|
+
const incomingBlocks = hashableContentBlocks(incomingBoundary.content);
|
|
19731
|
+
const incomingBlockHashes = incomingBlocks.map((block) => hashNormalizedContent([block]));
|
|
19732
|
+
const preservesStoredBlocks = incomingBlocks.length === incomingBoundary.content.length && incomingBlockHashes.length > storedBlocks.length && storedBlocks.every((hash, index) => incomingBlockHashes[index] === hash);
|
|
19733
|
+
const appendedBlocks = incomingBlocks.slice(storedBlocks.length);
|
|
19734
|
+
const seenToolResultIds = new Set(incomingBlocks.slice(0, storedBlocks.length).filter((block) => block?.type === "tool_result" && typeof block.tool_use_id === "string").map((block) => block.tool_use_id));
|
|
19735
|
+
const hasOnlyNewToolResults = appendedBlocks.every((block) => {
|
|
19736
|
+
if (block?.type !== "tool_result" || typeof block.tool_use_id !== "string")
|
|
19737
|
+
return false;
|
|
19738
|
+
if (seenToolResultIds.has(block.tool_use_id))
|
|
19739
|
+
return false;
|
|
19740
|
+
seenToolResultIds.add(block.tool_use_id);
|
|
19741
|
+
return true;
|
|
19742
|
+
});
|
|
19743
|
+
if (preservesStoredBlocks && hasOnlyNewToolResults) {
|
|
19744
|
+
return {
|
|
19745
|
+
type: "continuation",
|
|
19746
|
+
session: cached,
|
|
19747
|
+
resumeFrom: boundary,
|
|
19748
|
+
resumeContentFrom: storedBlocks.length
|
|
19749
|
+
};
|
|
19750
|
+
}
|
|
19751
|
+
}
|
|
19752
|
+
}
|
|
19533
19753
|
if (prefixOverlap > 0 && suffixOverlap === 0 && messages.length <= cached.messageCount) {
|
|
19534
19754
|
let rollbackUuid;
|
|
19535
19755
|
if (cached.sdkMessageUuids) {
|
|
@@ -19676,7 +19896,7 @@ function lookupSharedSessionByClaudeId(claudeSessionId) {
|
|
|
19676
19896
|
}
|
|
19677
19897
|
return newest;
|
|
19678
19898
|
}
|
|
19679
|
-
function storeSharedSession(key, claudeSessionId, messageCount, lineageHash, messageHashes, sdkMessageUuids, contextUsage) {
|
|
19899
|
+
function storeSharedSession(key, claudeSessionId, messageCount, lineageHash, messageHashes, sdkMessageUuids, contextUsage, messageBlockHashes, passthroughResumeUuid) {
|
|
19680
19900
|
const path3 = getStorePath();
|
|
19681
19901
|
const lockPath = `${path3}.lock`;
|
|
19682
19902
|
const hasLock = skipLocking ? false : acquireLock(lockPath);
|
|
@@ -19694,7 +19914,9 @@ function storeSharedSession(key, claudeSessionId, messageCount, lineageHash, mes
|
|
|
19694
19914
|
messageCount: messageCount ?? existing?.messageCount ?? 0,
|
|
19695
19915
|
lineageHash: lineageHash ?? existing?.lineageHash,
|
|
19696
19916
|
messageHashes: messageHashes ?? existing?.messageHashes,
|
|
19917
|
+
messageBlockHashes: messageBlockHashes ?? existing?.messageBlockHashes,
|
|
19697
19918
|
sdkMessageUuids: sdkMessageUuids ?? existing?.sdkMessageUuids,
|
|
19919
|
+
passthroughResumeUuid: passthroughResumeUuid === undefined ? existing?.passthroughResumeUuid : passthroughResumeUuid ?? undefined,
|
|
19698
19920
|
contextUsage: contextUsage ?? existing?.contextUsage,
|
|
19699
19921
|
...previousClaudeSessionId ? { previousClaudeSessionId } : {}
|
|
19700
19922
|
};
|
|
@@ -19852,7 +20074,11 @@ function touchSession(state) {
|
|
|
19852
20074
|
}
|
|
19853
20075
|
function classifyLineage(state, messages, cacheKey2) {
|
|
19854
20076
|
const result = verifyLineage(state, messages);
|
|
19855
|
-
if (result.type === "
|
|
20077
|
+
if (result.type === "continuation" && result.resumeContentFrom !== undefined) {
|
|
20078
|
+
const msg = `Parallel tool-result continuation (key=${cacheKey2.slice(0, 8)}…): resume from message ${result.resumeFrom}, content block ${result.resumeContentFrom}.`;
|
|
20079
|
+
console.error(`[PROXY] ${msg}`);
|
|
20080
|
+
diagnosticLog2.lineage(msg);
|
|
20081
|
+
} else if (result.type === "compaction") {
|
|
19856
20082
|
const msg = `Compaction detected (key=${cacheKey2.slice(0, 8)}…): suffix overlap ${result.suffixOverlap}/${state.messageCount}, resume from incoming message ${result.resumeFrom}.`;
|
|
19857
20083
|
console.error(`[PROXY] ${msg}`);
|
|
19858
20084
|
diagnosticLog2.lineage(msg);
|
|
@@ -19884,7 +20110,9 @@ function lookupSession(sessionId, messages, workingDirectory) {
|
|
|
19884
20110
|
messageCount: shared.messageCount || 0,
|
|
19885
20111
|
lineageHash: shared.lineageHash || "",
|
|
19886
20112
|
messageHashes: shared.messageHashes,
|
|
20113
|
+
messageBlockHashes: shared.messageBlockHashes,
|
|
19887
20114
|
sdkMessageUuids: shared.sdkMessageUuids,
|
|
20115
|
+
passthroughResumeUuid: shared.passthroughResumeUuid,
|
|
19888
20116
|
contextUsage: shared.contextUsage
|
|
19889
20117
|
};
|
|
19890
20118
|
const result = classifyLineage(state, messages, sessionId);
|
|
@@ -19912,7 +20140,9 @@ function lookupSession(sessionId, messages, workingDirectory) {
|
|
|
19912
20140
|
messageCount: shared.messageCount || 0,
|
|
19913
20141
|
lineageHash: shared.lineageHash || "",
|
|
19914
20142
|
messageHashes: shared.messageHashes,
|
|
20143
|
+
messageBlockHashes: shared.messageBlockHashes,
|
|
19915
20144
|
sdkMessageUuids: shared.sdkMessageUuids,
|
|
20145
|
+
passthroughResumeUuid: shared.passthroughResumeUuid,
|
|
19916
20146
|
contextUsage: shared.contextUsage
|
|
19917
20147
|
};
|
|
19918
20148
|
const result = classifyLineage(state, messages, fp);
|
|
@@ -19945,24 +20175,29 @@ function getSessionByClaudeId(claudeSessionId) {
|
|
|
19945
20175
|
messageCount: shared.messageCount || 0,
|
|
19946
20176
|
lineageHash: shared.lineageHash || "",
|
|
19947
20177
|
messageHashes: shared.messageHashes,
|
|
20178
|
+
messageBlockHashes: shared.messageBlockHashes,
|
|
19948
20179
|
sdkMessageUuids: shared.sdkMessageUuids,
|
|
20180
|
+
passthroughResumeUuid: shared.passthroughResumeUuid,
|
|
19949
20181
|
contextUsage: shared.contextUsage
|
|
19950
20182
|
});
|
|
19951
20183
|
}
|
|
19952
20184
|
return newest;
|
|
19953
20185
|
}
|
|
19954
|
-
function storeSession(sessionId, messages, claudeSessionId, workingDirectory, sdkMessageUuids, contextUsage) {
|
|
20186
|
+
function storeSession(sessionId, messages, claudeSessionId, workingDirectory, sdkMessageUuids, contextUsage, passthroughResumeUuid) {
|
|
19955
20187
|
if (!claudeSessionId)
|
|
19956
20188
|
return;
|
|
19957
20189
|
const lineageHash = computeLineageHash(messages);
|
|
19958
20190
|
const messageHashes = computeMessageHashes(messages);
|
|
20191
|
+
const messageBlockHashes = computeMessageBlockHashes(messages);
|
|
19959
20192
|
const state = {
|
|
19960
20193
|
claudeSessionId,
|
|
19961
20194
|
lastAccess: Date.now(),
|
|
19962
20195
|
messageCount: messages?.length || 0,
|
|
19963
20196
|
lineageHash,
|
|
19964
20197
|
messageHashes,
|
|
20198
|
+
messageBlockHashes,
|
|
19965
20199
|
sdkMessageUuids,
|
|
20200
|
+
...passthroughResumeUuid ? { passthroughResumeUuid } : {},
|
|
19966
20201
|
...contextUsage ? { contextUsage } : {}
|
|
19967
20202
|
};
|
|
19968
20203
|
if (sessionId)
|
|
@@ -19972,14 +20207,14 @@ function storeSession(sessionId, messages, claudeSessionId, workingDirectory, sd
|
|
|
19972
20207
|
fingerprintCache.set(fp, state);
|
|
19973
20208
|
const key = sessionId || fp;
|
|
19974
20209
|
if (key) {
|
|
19975
|
-
storeSharedSession(key, claudeSessionId, state.messageCount, lineageHash, messageHashes, sdkMessageUuids, contextUsage);
|
|
20210
|
+
storeSharedSession(key, claudeSessionId, state.messageCount, lineageHash, messageHashes, sdkMessageUuids, contextUsage, messageBlockHashes, passthroughResumeUuid ?? null);
|
|
19976
20211
|
}
|
|
19977
20212
|
}
|
|
19978
20213
|
|
|
19979
20214
|
// src/proxy/server.ts
|
|
19980
20215
|
var exec2 = promisify3(execCallback);
|
|
19981
20216
|
var claudeExecutable = "";
|
|
19982
|
-
var UPSTREAM_IDLE_MS = 90000;
|
|
20217
|
+
var UPSTREAM_IDLE_MS = envInt("UPSTREAM_IDLE_MS", 90000);
|
|
19983
20218
|
function credentialStoreForProfile(profile) {
|
|
19984
20219
|
if (profile.type !== "claude-max")
|
|
19985
20220
|
return;
|
|
@@ -20566,8 +20801,11 @@ data: ${JSON.stringify(lastError)}
|
|
|
20566
20801
|
const isUndo = lineageResult.type === "undo";
|
|
20567
20802
|
const cachedSession = lineageResult.type !== "diverged" ? lineageResult.session : undefined;
|
|
20568
20803
|
const resumeSessionId = cachedSession?.claudeSessionId;
|
|
20804
|
+
const passthrough = adapter.instancePassthrough !== undefined ? adapter.instancePassthrough : pipelineCtx.passthrough !== undefined ? pipelineCtx.passthrough : envBool("PASSTHROUGH");
|
|
20569
20805
|
const resumeFrom = lineageResult.type === "continuation" || lineageResult.type === "compaction" ? lineageResult.resumeFrom : undefined;
|
|
20806
|
+
const resumeContentFrom = lineageResult.type === "continuation" ? lineageResult.resumeContentFrom : undefined;
|
|
20570
20807
|
const undoRollbackUuid = isUndo && lineageResult.type === "undo" ? lineageResult.rollbackUuid : undefined;
|
|
20808
|
+
const passthroughResumeUuid = passthrough && isResume ? cachedSession?.passthroughResumeUuid : undefined;
|
|
20571
20809
|
const msgSummary = body.messages?.map((m) => {
|
|
20572
20810
|
const contentTypes = Array.isArray(m.content) ? m.content.map((b) => b.type).join(",") : "string";
|
|
20573
20811
|
return `${m.role}[${contentTypes}]`;
|
|
@@ -20610,7 +20848,16 @@ data: ${JSON.stringify(lastError)}
|
|
|
20610
20848
|
if (isUndo && undoRollbackUuid) {
|
|
20611
20849
|
messagesToConvert = getLastUserMessage(allMessages);
|
|
20612
20850
|
} else if (isResume) {
|
|
20613
|
-
if (resumeFrom !== undefined && resumeFrom < allMessages.length) {
|
|
20851
|
+
if (resumeFrom !== undefined && resumeContentFrom !== undefined && resumeFrom < allMessages.length && Array.isArray(allMessages[resumeFrom]?.content)) {
|
|
20852
|
+
const boundaryMessage = allMessages[resumeFrom];
|
|
20853
|
+
messagesToConvert = [
|
|
20854
|
+
{
|
|
20855
|
+
...boundaryMessage,
|
|
20856
|
+
content: boundaryMessage.content.slice(resumeContentFrom)
|
|
20857
|
+
},
|
|
20858
|
+
...allMessages.slice(resumeFrom + 1)
|
|
20859
|
+
];
|
|
20860
|
+
} else if (resumeFrom !== undefined && resumeFrom < allMessages.length) {
|
|
20614
20861
|
messagesToConvert = allMessages.slice(resumeFrom);
|
|
20615
20862
|
} else {
|
|
20616
20863
|
messagesToConvert = getLastUserMessage(allMessages);
|
|
@@ -20659,6 +20906,13 @@ data: ${JSON.stringify(lastError)}
|
|
|
20659
20906
|
if (structuredMessages.length > 1) {
|
|
20660
20907
|
structuredMessages = consolidateMultimodalOntoLastUser(structuredMessages);
|
|
20661
20908
|
}
|
|
20909
|
+
if (passthroughResumeUuid && structuredMessages.length > 0) {
|
|
20910
|
+
structuredMessages.unshift({
|
|
20911
|
+
type: "user",
|
|
20912
|
+
message: { role: "user", content: PASSTHROUGH_CONTINUATION_LEAD_IN },
|
|
20913
|
+
parent_tool_use_id: null
|
|
20914
|
+
});
|
|
20915
|
+
}
|
|
20662
20916
|
} else {
|
|
20663
20917
|
const toolIndex = buildToolUseIndex(allMessages ?? messagesToConvert ?? []);
|
|
20664
20918
|
const promptTurns = (messagesToConvert ?? []).map((m) => {
|
|
@@ -20670,11 +20924,11 @@ data: ${JSON.stringify(lastError)}
|
|
|
20670
20924
|
}
|
|
20671
20925
|
return { role: "user", text: flattenUserContent(m.content, sanitizeOpts, toolIndex) };
|
|
20672
20926
|
});
|
|
20673
|
-
|
|
20927
|
+
const resumeDelta = promptTurns.map((t) => t.text).filter(Boolean).join(`
|
|
20674
20928
|
|
|
20675
|
-
`) || ""
|
|
20929
|
+
`) || "";
|
|
20930
|
+
textPrompt = isResume ? passthroughResumeUuid ? framePassthroughContinuation(resumeDelta) : resumeDelta : frameReplayTurns(promptTurns);
|
|
20676
20931
|
}
|
|
20677
|
-
const passthrough = adapter.instancePassthrough !== undefined ? adapter.instancePassthrough : pipelineCtx.passthrough !== undefined ? pipelineCtx.passthrough : envBool("PASSTHROUGH");
|
|
20678
20932
|
const settingSources = envBool("LOAD_CONTEXT") || sdkFeatures.claudeMd === "full" ? ["user", "project"] : sdkFeatures.claudeMd === "project" ? ["project"] : pipelineCtx.settingSources ?? [];
|
|
20679
20933
|
const capturedToolUses = [];
|
|
20680
20934
|
const capturedSignatures = new Set;
|
|
@@ -20842,6 +21096,7 @@ data: ${JSON.stringify(lastError)}
|
|
|
20842
21096
|
claudeLog("upstream.start", { mode: "non_stream", model });
|
|
20843
21097
|
let lastUsage;
|
|
20844
21098
|
let lastStopReason;
|
|
21099
|
+
let nextPassthroughResumeUuid;
|
|
20845
21100
|
try {
|
|
20846
21101
|
if (!claudeExecutable) {
|
|
20847
21102
|
claudeExecutable = await resolveClaudeExecutableAsync();
|
|
@@ -20878,8 +21133,8 @@ data: ${JSON.stringify(lastError)}
|
|
|
20878
21133
|
hasDeferredTools,
|
|
20879
21134
|
resumeSessionId,
|
|
20880
21135
|
isUndo,
|
|
20881
|
-
undoRollbackUuid,
|
|
20882
|
-
forkSession: busySessionFork || undefined,
|
|
21136
|
+
resumeSessionAtUuid: undoRollbackUuid ?? passthroughResumeUuid,
|
|
21137
|
+
forkSession: busySessionFork || Boolean(passthroughResumeUuid) || undefined,
|
|
20883
21138
|
sdkHooks,
|
|
20884
21139
|
blockedTools: pipelineCtx.blockedTools,
|
|
20885
21140
|
incompatibleTools: pipelineCtx.incompatibleTools,
|
|
@@ -20962,7 +21217,7 @@ data: ${JSON.stringify(lastError)}
|
|
|
20962
21217
|
hasDeferredTools,
|
|
20963
21218
|
resumeSessionId: undefined,
|
|
20964
21219
|
isUndo: false,
|
|
20965
|
-
|
|
21220
|
+
resumeSessionAtUuid: undefined,
|
|
20966
21221
|
sdkHooks,
|
|
20967
21222
|
blockedTools: pipelineCtx.blockedTools,
|
|
20968
21223
|
incompatibleTools: pipelineCtx.incompatibleTools,
|
|
@@ -21031,7 +21286,7 @@ data: ${JSON.stringify(lastError)}
|
|
|
21031
21286
|
hasDeferredTools,
|
|
21032
21287
|
resumeSessionId: undefined,
|
|
21033
21288
|
isUndo: false,
|
|
21034
|
-
|
|
21289
|
+
resumeSessionAtUuid: undefined,
|
|
21035
21290
|
sdkHooks,
|
|
21036
21291
|
blockedTools: pipelineCtx.blockedTools,
|
|
21037
21292
|
incompatibleTools: pipelineCtx.incompatibleTools,
|
|
@@ -21112,6 +21367,7 @@ data: ${JSON.stringify(lastError)}
|
|
|
21112
21367
|
if (message.type === "assistant") {
|
|
21113
21368
|
noteAssistantContent(earlyStop, message.message?.content);
|
|
21114
21369
|
} else if (message.type === "user") {
|
|
21370
|
+
nextPassthroughResumeUuid = resumeBoundaryUuid(message) ?? nextPassthroughResumeUuid;
|
|
21115
21371
|
noteUserContent(earlyStop, message.message?.content);
|
|
21116
21372
|
if (shouldEarlyStop(earlyStop)) {
|
|
21117
21373
|
earlyStopFired = true;
|
|
@@ -21351,7 +21607,7 @@ Subprocess stderr: ${stderrOutput}`;
|
|
|
21351
21607
|
]);
|
|
21352
21608
|
}
|
|
21353
21609
|
if (currentSessionId && !isIndependentSession && !sawDuplicateToolUse) {
|
|
21354
|
-
storeSession(profileSessionId, body.messages || [], currentSessionId, profileScopedCwd, sdkUuidMap, lastUsage);
|
|
21610
|
+
storeSession(profileSessionId, body.messages || [], currentSessionId, profileScopedCwd, sdkUuidMap, lastUsage, earlyStopFired ? nextPassthroughResumeUuid : null);
|
|
21355
21611
|
}
|
|
21356
21612
|
const responseSessionId = currentSessionId || resumeSessionId || `session_${Date.now()}`;
|
|
21357
21613
|
return new Response(JSON.stringify({
|
|
@@ -21383,6 +21639,7 @@ Subprocess stderr: ${stderrOutput}`;
|
|
|
21383
21639
|
let streamEventsSeen = 0;
|
|
21384
21640
|
let eventsForwarded = 0;
|
|
21385
21641
|
let textEventsForwarded = 0;
|
|
21642
|
+
let textCharsForwarded = 0;
|
|
21386
21643
|
let bytesSent = 0;
|
|
21387
21644
|
let streamClosed = false;
|
|
21388
21645
|
let awaitingEarlyStopDrain = false;
|
|
@@ -21414,7 +21671,30 @@ Subprocess stderr: ${stderrOutput}`;
|
|
|
21414
21671
|
let lastUsage;
|
|
21415
21672
|
let hasStructuredOutput = false;
|
|
21416
21673
|
let structuredOutput;
|
|
21674
|
+
let nextPassthroughResumeUuid;
|
|
21675
|
+
const silentTurnRecoveryEnabled = env("SILENT_TURN_RECOVERY") !== "0";
|
|
21676
|
+
let silentTurnRecoveryAttempted = false;
|
|
21677
|
+
let silentTurnRecovered = false;
|
|
21417
21678
|
const streamedToolUseIds = new Set;
|
|
21679
|
+
let pendingTerminalDelta = null;
|
|
21680
|
+
let terminalDeltaSent = false;
|
|
21681
|
+
const sendTerminalDelta = (stopReasonOverride) => {
|
|
21682
|
+
if (terminalDeltaSent)
|
|
21683
|
+
return;
|
|
21684
|
+
const payload = stopReasonOverride ? encoder.encode(`event: message_delta
|
|
21685
|
+
data: ${JSON.stringify({
|
|
21686
|
+
type: "message_delta",
|
|
21687
|
+
delta: { stop_reason: stopReasonOverride, stop_sequence: null },
|
|
21688
|
+
usage: { output_tokens: lastUsage?.output_tokens ?? 0 }
|
|
21689
|
+
})}
|
|
21690
|
+
|
|
21691
|
+
`) : pendingTerminalDelta;
|
|
21692
|
+
if (!payload)
|
|
21693
|
+
return;
|
|
21694
|
+
terminalDeltaSent = true;
|
|
21695
|
+
if (safeEnqueue(payload, "terminal_message_delta"))
|
|
21696
|
+
eventsForwarded += 1;
|
|
21697
|
+
};
|
|
21418
21698
|
const openClientBlocks = new Set;
|
|
21419
21699
|
const resolvePendingStore = passthrough && earlyStopEnabled && !isIndependentSession && profileSessionId ? registerPendingStore(profileSessionId) : () => {};
|
|
21420
21700
|
let pendingEarlyStop = false;
|
|
@@ -21430,10 +21710,7 @@ Subprocess stderr: ${stderrOutput}`;
|
|
|
21430
21710
|
});
|
|
21431
21711
|
pendingEarlyStop = false;
|
|
21432
21712
|
flushOpenClientBlocks("early_stop");
|
|
21433
|
-
|
|
21434
|
-
data: ${JSON.stringify({ type: "message_delta", delta: { stop_reason: "tool_use", stop_sequence: null }, usage: { output_tokens: lastUsage?.output_tokens ?? 0 } })}
|
|
21435
|
-
|
|
21436
|
-
`), "early_stop");
|
|
21713
|
+
sendTerminalDelta("tool_use");
|
|
21437
21714
|
safeEnqueue(encoder.encode(`event: message_stop
|
|
21438
21715
|
data: ${JSON.stringify({ type: "message_stop" })}
|
|
21439
21716
|
|
|
@@ -21463,8 +21740,8 @@ data: ${JSON.stringify({ type: "content_block_stop", index: idx })}
|
|
|
21463
21740
|
}
|
|
21464
21741
|
openClientBlocks.clear();
|
|
21465
21742
|
};
|
|
21743
|
+
let currentSessionId;
|
|
21466
21744
|
try {
|
|
21467
|
-
let currentSessionId;
|
|
21468
21745
|
const MAX_RATE_LIMIT_RETRIES = 2;
|
|
21469
21746
|
const RATE_LIMIT_BASE_DELAY_MS = 1000;
|
|
21470
21747
|
const response = async function* () {
|
|
@@ -21496,8 +21773,8 @@ data: ${JSON.stringify({ type: "content_block_stop", index: idx })}
|
|
|
21496
21773
|
hasDeferredTools,
|
|
21497
21774
|
resumeSessionId,
|
|
21498
21775
|
isUndo,
|
|
21499
|
-
undoRollbackUuid,
|
|
21500
|
-
forkSession: busySessionFork || undefined,
|
|
21776
|
+
resumeSessionAtUuid: undoRollbackUuid ?? passthroughResumeUuid,
|
|
21777
|
+
forkSession: busySessionFork || Boolean(passthroughResumeUuid) || undefined,
|
|
21501
21778
|
sdkHooks,
|
|
21502
21779
|
blockedTools: pipelineCtx.blockedTools,
|
|
21503
21780
|
incompatibleTools: pipelineCtx.incompatibleTools,
|
|
@@ -21579,7 +21856,7 @@ data: ${JSON.stringify({ type: "content_block_stop", index: idx })}
|
|
|
21579
21856
|
hasDeferredTools,
|
|
21580
21857
|
resumeSessionId: undefined,
|
|
21581
21858
|
isUndo: false,
|
|
21582
|
-
|
|
21859
|
+
resumeSessionAtUuid: undefined,
|
|
21583
21860
|
sdkHooks,
|
|
21584
21861
|
blockedTools: pipelineCtx.blockedTools,
|
|
21585
21862
|
incompatibleTools: pipelineCtx.incompatibleTools,
|
|
@@ -21648,7 +21925,7 @@ data: ${JSON.stringify({ type: "content_block_stop", index: idx })}
|
|
|
21648
21925
|
hasDeferredTools,
|
|
21649
21926
|
resumeSessionId: undefined,
|
|
21650
21927
|
isUndo: false,
|
|
21651
|
-
|
|
21928
|
+
resumeSessionAtUuid: undefined,
|
|
21652
21929
|
sdkHooks,
|
|
21653
21930
|
blockedTools: pipelineCtx.blockedTools,
|
|
21654
21931
|
incompatibleTools: pipelineCtx.incompatibleTools,
|
|
@@ -21761,6 +22038,7 @@ data: ${JSON.stringify({ type: "content_block_stop", index: idx })}
|
|
|
21761
22038
|
if (message.type === "assistant" && message.uuid) {
|
|
21762
22039
|
sdkUuidMap.push(message.uuid);
|
|
21763
22040
|
}
|
|
22041
|
+
nextPassthroughResumeUuid = resumeBoundaryUuid(message) ?? nextPassthroughResumeUuid;
|
|
21764
22042
|
if (earlyStopEnabled) {
|
|
21765
22043
|
if (message.type === "assistant") {
|
|
21766
22044
|
noteAssistantContent(earlyStop, message.message?.content);
|
|
@@ -21832,10 +22110,7 @@ data: ${JSON.stringify({ type: "content_block_stop", index: idx })}
|
|
|
21832
22110
|
if (messageStartEmitted) {
|
|
21833
22111
|
if (passthrough && streamedToolUseIds.size > 0) {
|
|
21834
22112
|
flushOpenClientBlocks("turn2_suppression");
|
|
21835
|
-
|
|
21836
|
-
data: ${JSON.stringify({ type: "message_delta", delta: { stop_reason: "tool_use", stop_sequence: null }, usage: { output_tokens: lastUsage?.output_tokens ?? 0 } })}
|
|
21837
|
-
|
|
21838
|
-
`), "passthrough_turn2_stop");
|
|
22113
|
+
sendTerminalDelta("tool_use");
|
|
21839
22114
|
safeEnqueue(encoder.encode(`event: message_stop
|
|
21840
22115
|
data: ${JSON.stringify({ type: "message_stop" })}
|
|
21841
22116
|
|
|
@@ -21939,15 +22214,26 @@ data: ${JSON.stringify({
|
|
|
21939
22214
|
}
|
|
21940
22215
|
}
|
|
21941
22216
|
}
|
|
22217
|
+
if (eventType === "content_block_delta" && event.delta?.type === "text_delta" && shouldInjectSilentTurn({
|
|
22218
|
+
raw: env("DEBUG_FORCE_SILENT_TURN"),
|
|
22219
|
+
sessionId: agentSessionId
|
|
22220
|
+
})) {
|
|
22221
|
+
claudeLog("debug.silent_turn_injected", { sessionId: agentSessionId });
|
|
22222
|
+
continue;
|
|
22223
|
+
}
|
|
21942
22224
|
stripNonStandardStreamFields(event);
|
|
21943
22225
|
const payload = encoder.encode(`event: ${eventType}
|
|
21944
22226
|
data: ${JSON.stringify(event)}
|
|
21945
22227
|
|
|
21946
22228
|
`);
|
|
21947
|
-
if (
|
|
21948
|
-
|
|
22229
|
+
if (eventType === "message_delta") {
|
|
22230
|
+
pendingTerminalDelta = payload;
|
|
22231
|
+
} else {
|
|
22232
|
+
if (!safeEnqueue(payload, `stream_event:${eventType}`)) {
|
|
22233
|
+
break;
|
|
22234
|
+
}
|
|
22235
|
+
eventsForwarded += 1;
|
|
21949
22236
|
}
|
|
21950
|
-
eventsForwarded += 1;
|
|
21951
22237
|
if (eventType === "content_block_start") {
|
|
21952
22238
|
const idx = event.index;
|
|
21953
22239
|
if (typeof idx === "number")
|
|
@@ -21963,6 +22249,7 @@ data: ${JSON.stringify(event)}
|
|
|
21963
22249
|
}
|
|
21964
22250
|
if (passthrough && eventType === "message_delta" && event.delta?.stop_reason === "tool_use" && streamedToolUseIds.size > 0) {
|
|
21965
22251
|
flushOpenClientBlocks("drain_close");
|
|
22252
|
+
sendTerminalDelta();
|
|
21966
22253
|
safeEnqueue(encoder.encode(`event: message_stop
|
|
21967
22254
|
data: ${JSON.stringify({ type: "message_stop" })}
|
|
21968
22255
|
|
|
@@ -21979,6 +22266,8 @@ data: ${JSON.stringify({ type: "message_stop" })}
|
|
|
21979
22266
|
const delta = event.delta;
|
|
21980
22267
|
if (delta?.type === "text_delta") {
|
|
21981
22268
|
textEventsForwarded += 1;
|
|
22269
|
+
if (typeof delta.text === "string")
|
|
22270
|
+
textCharsForwarded += delta.text.length;
|
|
21982
22271
|
}
|
|
21983
22272
|
}
|
|
21984
22273
|
}
|
|
@@ -22040,6 +22329,7 @@ data: ${JSON.stringify({
|
|
|
22040
22329
|
messageStartEmitted = true;
|
|
22041
22330
|
eventsForwarded += 5;
|
|
22042
22331
|
textEventsForwarded += 1;
|
|
22332
|
+
textCharsForwarded += text.length;
|
|
22043
22333
|
}
|
|
22044
22334
|
if (passthrough) {
|
|
22045
22335
|
recordEnvelopeViolations(checkUndeliveredToolUses(capturedToolUses, streamedToolUseIds));
|
|
@@ -22065,9 +22355,125 @@ data: ${JSON.stringify({
|
|
|
22065
22355
|
plog(`[PROXY] ${requestMeta.requestId} discovered=${discoveredTools.size} (${newNames}) session_total=${allNames.length}`);
|
|
22066
22356
|
}
|
|
22067
22357
|
if (currentSessionId && !isIndependentSession && !sawDuplicateToolUse) {
|
|
22068
|
-
storeSession(profileSessionId, body.messages || [], currentSessionId, profileScopedCwd, sdkUuidMap, lastUsage);
|
|
22358
|
+
storeSession(profileSessionId, body.messages || [], currentSessionId, profileScopedCwd, sdkUuidMap, lastUsage, earlyStopFired ? nextPassthroughResumeUuid : null);
|
|
22069
22359
|
}
|
|
22070
22360
|
resolvePendingStore();
|
|
22361
|
+
const classifyNow = () => classifyTurnOutcome({
|
|
22362
|
+
textEvents: textEventsForwarded,
|
|
22363
|
+
toolUses: streamedToolUseIds.size,
|
|
22364
|
+
blocksForwarded: eventsForwarded
|
|
22365
|
+
});
|
|
22366
|
+
const preRecoveryOutcome = classifyNow();
|
|
22367
|
+
if (!streamClosed && messageStartEmitted && shouldAttemptRecovery({
|
|
22368
|
+
outcome: preRecoveryOutcome,
|
|
22369
|
+
alreadyAttempted: silentTurnRecoveryAttempted,
|
|
22370
|
+
clientGone: streamClosed,
|
|
22371
|
+
sessionId: currentSessionId || resumeSessionId,
|
|
22372
|
+
enabled: silentTurnRecoveryEnabled
|
|
22373
|
+
})) {
|
|
22374
|
+
silentTurnRecoveryAttempted = true;
|
|
22375
|
+
const capturedBeforeRecovery = capturedToolUses.length;
|
|
22376
|
+
claudeLog("response.silent_turn_recovery", {
|
|
22377
|
+
mode: "stream",
|
|
22378
|
+
kind: preRecoveryOutcome.kind,
|
|
22379
|
+
reason: preRecoveryOutcome.kind === "silent" ? preRecoveryOutcome.reason : undefined,
|
|
22380
|
+
sdkSessionId: currentSessionId || resumeSessionId
|
|
22381
|
+
});
|
|
22382
|
+
const recoveryLifter = createRecoveryLifter(() => nextClientBlockIndex++);
|
|
22383
|
+
let recoverySessionId;
|
|
22384
|
+
let recoveryBoundaryUuid;
|
|
22385
|
+
try {
|
|
22386
|
+
for await (const event of guardUpstreamIdle(query(buildQueryOptions({
|
|
22387
|
+
prompt: SILENT_TURN_NUDGE,
|
|
22388
|
+
model,
|
|
22389
|
+
workingDirectory,
|
|
22390
|
+
clientWorkingDirectory,
|
|
22391
|
+
systemContext,
|
|
22392
|
+
claudeExecutable,
|
|
22393
|
+
passthrough,
|
|
22394
|
+
stream: true,
|
|
22395
|
+
sdkAgents,
|
|
22396
|
+
passthroughMcp,
|
|
22397
|
+
cleanEnv: profileEnv,
|
|
22398
|
+
envOverrides,
|
|
22399
|
+
hasDeferredTools,
|
|
22400
|
+
resumeSessionId: currentSessionId || resumeSessionId,
|
|
22401
|
+
isUndo: false,
|
|
22402
|
+
resumeSessionAtUuid: nextPassthroughResumeUuid,
|
|
22403
|
+
forkSession: true,
|
|
22404
|
+
sdkHooks,
|
|
22405
|
+
blockedTools: pipelineCtx.blockedTools,
|
|
22406
|
+
incompatibleTools: pipelineCtx.incompatibleTools,
|
|
22407
|
+
mcpServerName: adapter.getMcpServerName(),
|
|
22408
|
+
allowedMcpTools: pipelineCtx.allowedMcpTools,
|
|
22409
|
+
onStderr,
|
|
22410
|
+
effort,
|
|
22411
|
+
thinking,
|
|
22412
|
+
taskBudget,
|
|
22413
|
+
outputFormat,
|
|
22414
|
+
betas,
|
|
22415
|
+
settingSources,
|
|
22416
|
+
codeSystemPrompt: sdkFeatures.codeSystemPrompt,
|
|
22417
|
+
clientSystemPrompt: sdkFeatures.clientSystemPrompt === false ? false : undefined,
|
|
22418
|
+
memory: sdkFeatures.memory,
|
|
22419
|
+
dreaming: sdkFeatures.dreaming,
|
|
22420
|
+
sharedMemory: sdkFeatures.sharedMemory,
|
|
22421
|
+
webFetchPreflight: sdkFeatures.webFetchPreflight,
|
|
22422
|
+
claudeAiConnectors: sdkFeatures.claudeAiConnectors,
|
|
22423
|
+
maxBudgetUsd: sdkFeatures.maxBudgetUsd,
|
|
22424
|
+
fallbackModel: sdkFeatures.fallbackModel,
|
|
22425
|
+
sdkDebug: sdkFeatures.sdkDebug,
|
|
22426
|
+
additionalDirectories: sdkFeatures.additionalDirectories ? sdkFeatures.additionalDirectories.split(",").map((d) => d.trim()).filter(Boolean) : undefined,
|
|
22427
|
+
advisorModel
|
|
22428
|
+
}, requestAbort.controller)), UPSTREAM_IDLE_MS, (sinceLastMs) => claudeLog("upstream.stalled", { mode: "silent_recovery", model, sinceLastMs }))) {
|
|
22429
|
+
const recoveryMessage = event;
|
|
22430
|
+
if (recoveryMessage.session_id)
|
|
22431
|
+
recoverySessionId = recoveryMessage.session_id;
|
|
22432
|
+
recoveryBoundaryUuid = resumeBoundaryUuid(recoveryMessage) ?? recoveryBoundaryUuid;
|
|
22433
|
+
if (recoveryMessage.type !== "stream_event")
|
|
22434
|
+
continue;
|
|
22435
|
+
const lifted = recoveryLifter.lift(event.event);
|
|
22436
|
+
if (!lifted)
|
|
22437
|
+
continue;
|
|
22438
|
+
safeEnqueue(encoder.encode(`event: ${lifted.frame.type}
|
|
22439
|
+
data: ${JSON.stringify(lifted.frame)}
|
|
22440
|
+
|
|
22441
|
+
`), `silent_recovery_${lifted.kind}`);
|
|
22442
|
+
if (lifted.kind === "block_start") {
|
|
22443
|
+
eventsForwarded += 1;
|
|
22444
|
+
} else if (lifted.kind === "text_delta") {
|
|
22445
|
+
textEventsForwarded += 1;
|
|
22446
|
+
textCharsForwarded += lifted.textChars;
|
|
22447
|
+
silentTurnRecovered = true;
|
|
22448
|
+
}
|
|
22449
|
+
}
|
|
22450
|
+
} catch (recoveryError) {
|
|
22451
|
+
claudeLog("response.silent_turn_recovery_failed", {
|
|
22452
|
+
mode: "stream",
|
|
22453
|
+
error: recoveryError instanceof Error ? recoveryError.message : String(recoveryError)
|
|
22454
|
+
});
|
|
22455
|
+
}
|
|
22456
|
+
if (capturedToolUses.length > capturedBeforeRecovery) {
|
|
22457
|
+
silentTurnRecovered = true;
|
|
22458
|
+
}
|
|
22459
|
+
if (silentTurnRecovered && recoverySessionId && !isIndependentSession && !sawDuplicateToolUse) {
|
|
22460
|
+
currentSessionId = recoverySessionId;
|
|
22461
|
+
nextPassthroughResumeUuid = recoveryBoundaryUuid;
|
|
22462
|
+
sdkUuidMap.length = 0;
|
|
22463
|
+
for (let i = 0;i < allMessages.length; i++)
|
|
22464
|
+
sdkUuidMap.push(null);
|
|
22465
|
+
storeSession(profileSessionId, body.messages || [], recoverySessionId, profileScopedCwd, sdkUuidMap, lastUsage, recoveryBoundaryUuid ?? null);
|
|
22466
|
+
}
|
|
22467
|
+
claudeLog("response.silent_turn_recovery_result", {
|
|
22468
|
+
mode: "stream",
|
|
22469
|
+
recovered: silentTurnRecovered,
|
|
22470
|
+
textEvents: textEventsForwarded,
|
|
22471
|
+
forkedSession: recoverySessionId ?? null
|
|
22472
|
+
});
|
|
22473
|
+
if (silentTurnRecovered && preRecoveryOutcome.kind === "silent") {
|
|
22474
|
+
diagnosticLog2.session(`${requestMeta.requestId} silent_turn reason=${preRecoveryOutcome.reason} ` + `blocks=${eventsForwarded} out=${lastUsage?.output_tokens ?? 0} ` + `recovery=succeeded`, requestMeta.requestId);
|
|
22475
|
+
}
|
|
22476
|
+
}
|
|
22071
22477
|
if (!streamClosed) {
|
|
22072
22478
|
const unseenToolUses = capturedToolUses.filter((tu) => !streamedToolUseIds.has(tu.id));
|
|
22073
22479
|
if (passthrough && unseenToolUses.length > 0 && messageStartEmitted) {
|
|
@@ -22099,14 +22505,7 @@ data: ${JSON.stringify({
|
|
|
22099
22505
|
|
|
22100
22506
|
`), "passthrough_tool_block_stop");
|
|
22101
22507
|
}
|
|
22102
|
-
|
|
22103
|
-
data: ${JSON.stringify({
|
|
22104
|
-
type: "message_delta",
|
|
22105
|
-
delta: { stop_reason: "tool_use", stop_sequence: null },
|
|
22106
|
-
usage: { output_tokens: 0 }
|
|
22107
|
-
})}
|
|
22108
|
-
|
|
22109
|
-
`), "passthrough_message_delta");
|
|
22508
|
+
sendTerminalDelta("tool_use");
|
|
22110
22509
|
}
|
|
22111
22510
|
if (trackFileChanges && passthrough && pipelineCtx.extractFileChangesFromToolUse) {
|
|
22112
22511
|
const passthroughChanges = extractFileChangesFromMessages(body.messages || [], pipelineCtx.extractFileChangesFromToolUse);
|
|
@@ -22143,6 +22542,7 @@ data: ${JSON.stringify({
|
|
|
22143
22542
|
}
|
|
22144
22543
|
}
|
|
22145
22544
|
if (messageStartEmitted) {
|
|
22545
|
+
sendTerminalDelta();
|
|
22146
22546
|
safeEnqueue(encoder.encode(`event: message_stop
|
|
22147
22547
|
data: {"type":"message_stop"}
|
|
22148
22548
|
|
|
@@ -22208,13 +22608,18 @@ data: {"type":"message_stop"}
|
|
|
22208
22608
|
cacheHitRate: computeCacheHitRate(lastUsage),
|
|
22209
22609
|
...envelopeViolations.length > 0 ? { envelopeViolations: [...envelopeViolations] } : {}
|
|
22210
22610
|
});
|
|
22211
|
-
|
|
22212
|
-
|
|
22611
|
+
const turnOutcome = classifyNow();
|
|
22612
|
+
if (turnOutcome.kind === "silent") {
|
|
22613
|
+
claudeLog("response.silent_turn", {
|
|
22213
22614
|
model,
|
|
22615
|
+
reason: turnOutcome.reason,
|
|
22214
22616
|
streamEventsSeen,
|
|
22215
22617
|
eventsForwarded,
|
|
22216
|
-
|
|
22618
|
+
outputTokens: lastUsage?.output_tokens,
|
|
22619
|
+
recovered: silentTurnRecovered,
|
|
22620
|
+
recoveryAttempted: silentTurnRecoveryAttempted
|
|
22217
22621
|
});
|
|
22622
|
+
diagnosticLog2.session(`${requestMeta.requestId} silent_turn reason=${turnOutcome.reason} ` + `blocks=${eventsForwarded} out=${lastUsage?.output_tokens ?? 0} ` + `recovery=${silentTurnRecoveryAttempted ? silentTurnRecovered ? "succeeded" : "failed" : "off"}`, requestMeta.requestId);
|
|
22218
22623
|
}
|
|
22219
22624
|
}
|
|
22220
22625
|
} catch (error) {
|
|
@@ -22227,6 +22632,21 @@ data: {"type":"message_stop"}
|
|
|
22227
22632
|
textEventsForwarded,
|
|
22228
22633
|
durationMs: Date.now() - requestStartAt
|
|
22229
22634
|
});
|
|
22635
|
+
const disposition = clientAbortDisposition({
|
|
22636
|
+
isIndependentSession,
|
|
22637
|
+
profileSessionId,
|
|
22638
|
+
currentSessionId,
|
|
22639
|
+
sawDuplicateToolUse,
|
|
22640
|
+
resumeBoundaryUuid: nextPassthroughResumeUuid,
|
|
22641
|
+
passthrough
|
|
22642
|
+
});
|
|
22643
|
+
if (disposition.action === "store" && currentSessionId) {
|
|
22644
|
+
storeSession(profileSessionId, body.messages || [], currentSessionId, profileScopedCwd, sdkUuidMap, lastUsage, disposition.resumeUuid);
|
|
22645
|
+
} else if (disposition.action === "evict") {
|
|
22646
|
+
evictSession(profileSessionId, profileScopedCwd, body.messages || []);
|
|
22647
|
+
}
|
|
22648
|
+
claudeLog("passthrough.client_abort_settled", { action: disposition.action });
|
|
22649
|
+
resolvePendingStore();
|
|
22230
22650
|
return;
|
|
22231
22651
|
}
|
|
22232
22652
|
resolvePendingStore();
|
|
@@ -22380,26 +22800,41 @@ data: {"type":"message_stop"}
|
|
|
22380
22800
|
error: streamErr.type
|
|
22381
22801
|
});
|
|
22382
22802
|
if (messageStartEmitted) {
|
|
22803
|
+
const errorStopReason = textEventsForwarded > 0 ? "end_turn" : "max_tokens";
|
|
22804
|
+
claudeLog("response.error_envelope", {
|
|
22805
|
+
mode: "stream",
|
|
22806
|
+
stopReason: errorStopReason,
|
|
22807
|
+
textEvents: textEventsForwarded,
|
|
22808
|
+
classified: streamErr.type
|
|
22809
|
+
});
|
|
22383
22810
|
safeEnqueue(encoder.encode(`event: message_delta
|
|
22384
22811
|
data: ${JSON.stringify({
|
|
22385
22812
|
type: "message_delta",
|
|
22386
|
-
delta: { stop_reason:
|
|
22813
|
+
delta: { stop_reason: errorStopReason, stop_sequence: null },
|
|
22387
22814
|
usage: { output_tokens: 0 }
|
|
22388
22815
|
})}
|
|
22389
22816
|
|
|
22390
22817
|
`), "error_message_delta");
|
|
22818
|
+
safeEnqueue(encoder.encode(`event: error
|
|
22819
|
+
data: ${JSON.stringify({
|
|
22820
|
+
type: "error",
|
|
22821
|
+
error: { type: streamErr.type, message: streamErr.message }
|
|
22822
|
+
})}
|
|
22823
|
+
|
|
22824
|
+
`), "error_event_before_stop");
|
|
22391
22825
|
safeEnqueue(encoder.encode(`event: message_stop
|
|
22392
22826
|
data: {"type":"message_stop"}
|
|
22393
22827
|
|
|
22394
22828
|
`), "error_message_stop");
|
|
22395
|
-
}
|
|
22396
|
-
|
|
22829
|
+
} else {
|
|
22830
|
+
safeEnqueue(encoder.encode(`event: error
|
|
22397
22831
|
data: ${JSON.stringify({
|
|
22398
|
-
|
|
22399
|
-
|
|
22400
|
-
|
|
22832
|
+
type: "error",
|
|
22833
|
+
error: { type: streamErr.type, message: streamErr.message }
|
|
22834
|
+
})}
|
|
22401
22835
|
|
|
22402
22836
|
`), "error_event");
|
|
22837
|
+
}
|
|
22403
22838
|
if (!streamClosed) {
|
|
22404
22839
|
try {
|
|
22405
22840
|
controller.close();
|
|
@@ -22657,7 +23092,7 @@ data: ${JSON.stringify({
|
|
|
22657
23092
|
});
|
|
22658
23093
|
});
|
|
22659
23094
|
app.get("/profiles", async (c) => {
|
|
22660
|
-
const { profilePageHtml } = await import("./profilePage-
|
|
23095
|
+
const { profilePageHtml } = await import("./profilePage-gtazq15d.js");
|
|
22661
23096
|
return c.html(profilePageHtml);
|
|
22662
23097
|
});
|
|
22663
23098
|
app.post("/profiles/active", async (c) => {
|
|
@@ -22740,14 +23175,25 @@ data: ${JSON.stringify({
|
|
|
22740
23175
|
});
|
|
22741
23176
|
app.post("/v1/chat/completions", async (c) => {
|
|
22742
23177
|
const rawBody = await c.req.json();
|
|
22743
|
-
const
|
|
23178
|
+
const userAgent = c.req.header("user-agent") ?? "";
|
|
23179
|
+
const jcodeSessionId = userAgent.startsWith("jcode/") ? normalizeJcodeSessionId(c.req.header("x-jcode-session")) : undefined;
|
|
23180
|
+
const isJcode = jcodeSessionId !== undefined;
|
|
23181
|
+
const adapterName = isJcode ? "jcode" : "openai";
|
|
23182
|
+
const anthropicBody = translateOpenAiToAnthropic(rawBody, {
|
|
23183
|
+
preserveConversationHistory: isJcode
|
|
23184
|
+
});
|
|
22744
23185
|
if (!anthropicBody) {
|
|
22745
23186
|
return c.json({ type: "error", error: { type: "invalid_request_error", message: "messages: Field required" } }, 400);
|
|
22746
23187
|
}
|
|
22747
23188
|
const internalHeaders = {
|
|
22748
23189
|
"Content-Type": "application/json",
|
|
22749
|
-
"x-meridian-agent":
|
|
23190
|
+
"x-meridian-agent": adapterName
|
|
22750
23191
|
};
|
|
23192
|
+
if (jcodeSessionId)
|
|
23193
|
+
internalHeaders["x-jcode-session"] = jcodeSessionId;
|
|
23194
|
+
const requestedProfile = c.req.header("x-meridian-profile");
|
|
23195
|
+
if (requestedProfile)
|
|
23196
|
+
internalHeaders["x-meridian-profile"] = requestedProfile;
|
|
22751
23197
|
const xApiKey = c.req.header("x-api-key");
|
|
22752
23198
|
if (xApiKey)
|
|
22753
23199
|
internalHeaders["x-api-key"] = xApiKey;
|
|
@@ -22768,7 +23214,7 @@ data: ${JSON.stringify({
|
|
|
22768
23214
|
const created = Math.floor(Date.now() / 1000);
|
|
22769
23215
|
const model = typeof rawBody.model === "string" && rawBody.model ? rawBody.model : CANONICAL_SONNET_MODEL;
|
|
22770
23216
|
const { getFeaturesForAdapter: getFeaturesForAdapter2 } = (init_sdkFeatures(), __toCommonJS(exports_sdkFeatures));
|
|
22771
|
-
const sdkFeatures = getFeaturesForAdapter2(
|
|
23217
|
+
const sdkFeatures = getFeaturesForAdapter2(adapterName);
|
|
22772
23218
|
if (!anthropicBody.stream) {
|
|
22773
23219
|
const anthropicRes = await internalRes.json();
|
|
22774
23220
|
return c.json(translateAnthropicToOpenAi(anthropicRes, completionId, model, created, {
|
|
@@ -23014,7 +23460,7 @@ data: ${JSON.stringify({ response: { id: responseId, status: "failed", error: {
|
|
|
23014
23460
|
const profilesList = getEffectiveProfiles(finalConfig.profiles);
|
|
23015
23461
|
const activeId = getActiveProfileId() || finalConfig.defaultProfile || profilesList[0]?.id || null;
|
|
23016
23462
|
if (profilesList.length === 0) {
|
|
23017
|
-
const oauth = await
|
|
23463
|
+
const { snapshot: oauth, error } = await fetchOAuthUsageResult({});
|
|
23018
23464
|
return c.json({
|
|
23019
23465
|
profiles: [{
|
|
23020
23466
|
id: "default",
|
|
@@ -23022,7 +23468,7 @@ data: ${JSON.stringify({ response: { id: responseId, status: "failed", error: {
|
|
|
23022
23468
|
windows: oauth?.windows ?? [],
|
|
23023
23469
|
extraUsage: oauth?.extraUsage ?? null,
|
|
23024
23470
|
fetchedAt: oauth?.fetchedAt ?? null,
|
|
23025
|
-
error
|
|
23471
|
+
error
|
|
23026
23472
|
}],
|
|
23027
23473
|
activeProfile: "default",
|
|
23028
23474
|
asOf: Date.now()
|
|
@@ -23041,7 +23487,7 @@ data: ${JSON.stringify({ response: { id: responseId, status: "failed", error: {
|
|
|
23041
23487
|
error: "not_oauth"
|
|
23042
23488
|
};
|
|
23043
23489
|
}
|
|
23044
|
-
const oauth = await
|
|
23490
|
+
const { snapshot: oauth, error } = await fetchOAuthUsageResult({
|
|
23045
23491
|
profileId: p.id,
|
|
23046
23492
|
claudeConfigDir: p.claudeConfigDir
|
|
23047
23493
|
});
|
|
@@ -23052,7 +23498,7 @@ data: ${JSON.stringify({ response: { id: responseId, status: "failed", error: {
|
|
|
23052
23498
|
windows: oauth?.windows ?? [],
|
|
23053
23499
|
extraUsage: oauth?.extraUsage ?? null,
|
|
23054
23500
|
fetchedAt: oauth?.fetchedAt ?? null,
|
|
23055
|
-
error
|
|
23501
|
+
error
|
|
23056
23502
|
};
|
|
23057
23503
|
}));
|
|
23058
23504
|
return c.json({
|