clawmux 0.2.2 → 0.2.3
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/dist/cli.cjs +1 -1
- package/dist/index.cjs +117 -9
- package/package.json +1 -1
package/dist/cli.cjs
CHANGED
|
@@ -317,7 +317,7 @@ function getLogDir() {
|
|
|
317
317
|
}
|
|
318
318
|
|
|
319
319
|
// src/cli.ts
|
|
320
|
-
var VERSION2 = process.env.npm_package_version ?? "0.2.
|
|
320
|
+
var VERSION2 = process.env.npm_package_version ?? "0.2.3";
|
|
321
321
|
var SERVICE_NAME = "clawmux";
|
|
322
322
|
var HELP = `Usage: clawmux <command>
|
|
323
323
|
|
package/dist/index.cjs
CHANGED
|
@@ -1892,6 +1892,98 @@ class OllamaAdapter {
|
|
|
1892
1892
|
var ollamaAdapter = new OllamaAdapter;
|
|
1893
1893
|
registerAdapter(ollamaAdapter);
|
|
1894
1894
|
|
|
1895
|
+
// src/utils/aws-sigv4.ts
|
|
1896
|
+
var import_node_crypto = require("node:crypto");
|
|
1897
|
+
var SERVICE = "bedrock";
|
|
1898
|
+
function sha256(data) {
|
|
1899
|
+
return import_node_crypto.createHash("sha256").update(data).digest("hex");
|
|
1900
|
+
}
|
|
1901
|
+
function hmacSha256(key, data) {
|
|
1902
|
+
return import_node_crypto.createHmac("sha256", key).update(data).digest();
|
|
1903
|
+
}
|
|
1904
|
+
function hmacSha256Hex(key, data) {
|
|
1905
|
+
return import_node_crypto.createHmac("sha256", key).update(data).digest("hex");
|
|
1906
|
+
}
|
|
1907
|
+
function awsUriEncode(str) {
|
|
1908
|
+
return encodeURIComponent(str).replace(/!/g, "%21").replace(/'/g, "%27").replace(/\(/g, "%28").replace(/\)/g, "%29").replace(/\*/g, "%2A");
|
|
1909
|
+
}
|
|
1910
|
+
function buildCanonicalUri(pathname) {
|
|
1911
|
+
if (pathname === "" || pathname === "/")
|
|
1912
|
+
return "/";
|
|
1913
|
+
const segments = pathname.split("/");
|
|
1914
|
+
return segments.map((segment) => segment === "" ? "" : awsUriEncode(awsUriEncode(segment))).join("/");
|
|
1915
|
+
}
|
|
1916
|
+
function formatDateStamp(date) {
|
|
1917
|
+
return date.toISOString().slice(0, 10).replace(/-/g, "");
|
|
1918
|
+
}
|
|
1919
|
+
function formatAmzDate(date) {
|
|
1920
|
+
return date.toISOString().replace(/[-:]/g, "").replace(/\.\d{3}/, "");
|
|
1921
|
+
}
|
|
1922
|
+
function deriveSigningKey(secretKey, dateStamp, region, service) {
|
|
1923
|
+
const kDate = hmacSha256(`AWS4${secretKey}`, dateStamp);
|
|
1924
|
+
const kRegion = hmacSha256(kDate, region);
|
|
1925
|
+
const kService = hmacSha256(kRegion, service);
|
|
1926
|
+
return hmacSha256(kService, "aws4_request");
|
|
1927
|
+
}
|
|
1928
|
+
function signRequest(request, credentials, now) {
|
|
1929
|
+
const date = now ?? new Date;
|
|
1930
|
+
const dateStamp = formatDateStamp(date);
|
|
1931
|
+
const amzDate = formatAmzDate(date);
|
|
1932
|
+
const url = new URL(request.url);
|
|
1933
|
+
const canonicalUri = buildCanonicalUri(url.pathname);
|
|
1934
|
+
const sortedParams = [...url.searchParams.entries()].sort((a, b) => a[0].localeCompare(b[0]));
|
|
1935
|
+
const canonicalQueryString = sortedParams.map(([k, v]) => `${awsUriEncode(k)}=${awsUriEncode(v)}`).join("&");
|
|
1936
|
+
const payloadHash = sha256(request.body);
|
|
1937
|
+
const headersToSign = {};
|
|
1938
|
+
for (const [k, v] of Object.entries(request.headers)) {
|
|
1939
|
+
headersToSign[k.toLowerCase()] = v.trim();
|
|
1940
|
+
}
|
|
1941
|
+
headersToSign["host"] = url.host;
|
|
1942
|
+
headersToSign["x-amz-date"] = amzDate;
|
|
1943
|
+
headersToSign["x-amz-content-sha256"] = payloadHash;
|
|
1944
|
+
if (credentials.sessionToken) {
|
|
1945
|
+
headersToSign["x-amz-security-token"] = credentials.sessionToken;
|
|
1946
|
+
}
|
|
1947
|
+
const sortedHeaderKeys = Object.keys(headersToSign).sort();
|
|
1948
|
+
const canonicalHeaders = sortedHeaderKeys.map((k) => `${k}:${headersToSign[k]}`).join(`
|
|
1949
|
+
`) + `
|
|
1950
|
+
`;
|
|
1951
|
+
const signedHeaders = sortedHeaderKeys.join(";");
|
|
1952
|
+
const canonicalRequest = [
|
|
1953
|
+
request.method,
|
|
1954
|
+
canonicalUri,
|
|
1955
|
+
canonicalQueryString,
|
|
1956
|
+
canonicalHeaders,
|
|
1957
|
+
signedHeaders,
|
|
1958
|
+
payloadHash
|
|
1959
|
+
].join(`
|
|
1960
|
+
`);
|
|
1961
|
+
const credentialScope = `${dateStamp}/${credentials.region}/${SERVICE}/aws4_request`;
|
|
1962
|
+
const stringToSign = [
|
|
1963
|
+
"AWS4-HMAC-SHA256",
|
|
1964
|
+
amzDate,
|
|
1965
|
+
credentialScope,
|
|
1966
|
+
sha256(canonicalRequest)
|
|
1967
|
+
].join(`
|
|
1968
|
+
`);
|
|
1969
|
+
const signingKey = deriveSigningKey(credentials.secretAccessKey, dateStamp, credentials.region, SERVICE);
|
|
1970
|
+
const signature = hmacSha256Hex(signingKey, stringToSign);
|
|
1971
|
+
const authorization = `AWS4-HMAC-SHA256 Credential=${credentials.accessKeyId}/${credentialScope}, ` + `SignedHeaders=${signedHeaders}, Signature=${signature}`;
|
|
1972
|
+
const result = {
|
|
1973
|
+
Authorization: authorization,
|
|
1974
|
+
"x-amz-date": amzDate,
|
|
1975
|
+
"x-amz-content-sha256": payloadHash
|
|
1976
|
+
};
|
|
1977
|
+
if (credentials.sessionToken) {
|
|
1978
|
+
result["x-amz-security-token"] = credentials.sessionToken;
|
|
1979
|
+
}
|
|
1980
|
+
return result;
|
|
1981
|
+
}
|
|
1982
|
+
function extractRegionFromUrl(url) {
|
|
1983
|
+
const match = url.match(/\.([a-z0-9-]+)\.amazonaws\.com/);
|
|
1984
|
+
return match?.[1];
|
|
1985
|
+
}
|
|
1986
|
+
|
|
1895
1987
|
// src/adapters/bedrock.ts
|
|
1896
1988
|
function bedrockMessagesToStandard(messages) {
|
|
1897
1989
|
return messages.map((m) => {
|
|
@@ -1988,18 +2080,23 @@ class BedrockAdapter {
|
|
|
1988
2080
|
maxTokens: parsed.maxTokens
|
|
1989
2081
|
};
|
|
1990
2082
|
}
|
|
2083
|
+
const url = `${baseUrl}/model/${targetModel}/converse-stream`;
|
|
2084
|
+
const body = JSON.stringify(requestBody);
|
|
1991
2085
|
const headers = {
|
|
1992
2086
|
"Content-Type": "application/json"
|
|
1993
2087
|
};
|
|
1994
|
-
if (auth.
|
|
2088
|
+
if (auth.awsAccessKeyId && auth.awsSecretKey && auth.awsRegion) {
|
|
2089
|
+
const sigv4Headers = signRequest({ method: "POST", url, headers, body }, {
|
|
2090
|
+
accessKeyId: auth.awsAccessKeyId,
|
|
2091
|
+
secretAccessKey: auth.awsSecretKey,
|
|
2092
|
+
sessionToken: auth.awsSessionToken,
|
|
2093
|
+
region: auth.awsRegion
|
|
2094
|
+
});
|
|
2095
|
+
Object.assign(headers, sigv4Headers);
|
|
2096
|
+
} else if (auth.apiKey) {
|
|
1995
2097
|
headers[auth.headerName || "Authorization"] = auth.headerValue || auth.apiKey;
|
|
1996
2098
|
}
|
|
1997
|
-
return {
|
|
1998
|
-
url: `${baseUrl}/model/${targetModel}/converse-stream`,
|
|
1999
|
-
method: "POST",
|
|
2000
|
-
headers,
|
|
2001
|
-
body: JSON.stringify(requestBody)
|
|
2002
|
-
};
|
|
2099
|
+
return { url, method: "POST", headers, body };
|
|
2003
2100
|
}
|
|
2004
2101
|
modifyMessages(rawBody, compressedMessages) {
|
|
2005
2102
|
return {
|
|
@@ -2726,10 +2823,17 @@ function formatAuth(apiKey, providerConfig) {
|
|
|
2726
2823
|
return { apiKey, headerName: "x-goog-api-key", headerValue: apiKey };
|
|
2727
2824
|
}
|
|
2728
2825
|
if (api === "bedrock-converse-stream") {
|
|
2826
|
+
const secretKey = process.env.AWS_SECRET_ACCESS_KEY ?? "";
|
|
2827
|
+
const sessionToken = process.env.AWS_SESSION_TOKEN;
|
|
2828
|
+
const region = process.env.AWS_REGION ?? process.env.AWS_DEFAULT_REGION ?? extractRegionFromUrl(providerConfig?.baseUrl ?? "") ?? "us-east-1";
|
|
2729
2829
|
return {
|
|
2730
2830
|
apiKey,
|
|
2731
2831
|
headerName: "Authorization",
|
|
2732
|
-
headerValue: "
|
|
2832
|
+
headerValue: "",
|
|
2833
|
+
awsAccessKeyId: apiKey,
|
|
2834
|
+
awsSecretKey: secretKey,
|
|
2835
|
+
awsSessionToken: sessionToken,
|
|
2836
|
+
awsRegion: region
|
|
2733
2837
|
};
|
|
2734
2838
|
}
|
|
2735
2839
|
return { apiKey, headerName: "Authorization", headerValue: `Bearer ${apiKey}` };
|
|
@@ -3365,7 +3469,11 @@ async function handleApiRequest(req, body, apiType, config, openclawConfig, auth
|
|
|
3365
3469
|
const authInfo = {
|
|
3366
3470
|
apiKey: auth.apiKey,
|
|
3367
3471
|
headerName: auth.headerName,
|
|
3368
|
-
headerValue: auth.headerValue
|
|
3472
|
+
headerValue: auth.headerValue,
|
|
3473
|
+
awsAccessKeyId: auth.awsAccessKeyId,
|
|
3474
|
+
awsSecretKey: auth.awsSecretKey,
|
|
3475
|
+
awsSessionToken: auth.awsSessionToken,
|
|
3476
|
+
awsRegion: auth.awsRegion
|
|
3369
3477
|
};
|
|
3370
3478
|
const actualModelId = decision.model.split("/").slice(1).join("/");
|
|
3371
3479
|
const isCrossProvider = targetApiType !== "" && targetApiType !== apiType;
|