@wrongstack/core 0.270.0 → 0.272.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/dist/{agent-bridge-PcHQl_UQ.d.ts → agent-bridge-jVSZiygR.d.ts} +1 -1
- package/dist/{agent-subagent-runner-SHJW7t8q.d.ts → agent-subagent-runner-DOLIwBRo.d.ts} +7 -7
- package/dist/{brain-BYcK__Ym.d.ts → brain-CdbbJWi3.d.ts} +71 -1
- package/dist/{compactor-C2RKEBtC.d.ts → compactor-72ug-ZRB.d.ts} +1 -1
- package/dist/{config-C_ae2k86.d.ts → config-D2DGoGSQ.d.ts} +29 -2
- package/dist/{context-Dp87Bcaq.d.ts → context-Dw55zZ_Q.d.ts} +110 -1
- package/dist/coordination/index.d.ts +121 -17
- package/dist/coordination/index.js +738 -74
- package/dist/coordination/index.js.map +1 -1
- package/dist/defaults/index.d.ts +25 -25
- package/dist/defaults/index.js +599 -86
- package/dist/defaults/index.js.map +1 -1
- package/dist/execution/index.d.ts +23 -18
- package/dist/execution/index.js +136 -41
- package/dist/execution/index.js.map +1 -1
- package/dist/execution/prompt-enhancer.d.ts +36 -6
- package/dist/execution/prompt-enhancer.js +35 -9
- package/dist/execution/prompt-enhancer.js.map +1 -1
- package/dist/extension/index.d.ts +6 -6
- package/dist/{global-mailbox-Bvrz1P3f.d.ts → global-mailbox-CQj_C9Dp.d.ts} +139 -3
- package/dist/{goal-preamble-CA_4yiGQ.d.ts → goal-preamble-ZXDjjR1y.d.ts} +9 -9
- package/dist/{goal-store-DhuJoUNG.d.ts → goal-store-CcJBd-g1.d.ts} +1 -1
- package/dist/hq/index.d.ts +93 -6
- package/dist/hq/index.js +616 -46
- package/dist/hq/index.js.map +1 -1
- package/dist/{index-whDfTANu.d.ts → index-2Lhk5v0o.d.ts} +2 -2
- package/dist/{index-CZQ6Pwbs.d.ts → index-BL7BAx0p.d.ts} +8 -8
- package/dist/{index-W4VJCzHa.d.ts → index-Qo4kTzgw.d.ts} +5 -5
- package/dist/index.d.ts +96 -56
- package/dist/index.js +1938 -349
- package/dist/index.js.map +1 -1
- package/dist/infrastructure/index.d.ts +6 -6
- package/dist/infrastructure/index.js +5 -3
- package/dist/infrastructure/index.js.map +1 -1
- package/dist/kernel/index.d.ts +9 -9
- package/dist/kernel/index.js.map +1 -1
- package/dist/{mcp-servers-DJdZiRcv.d.ts → mcp-servers-DS-YUXvF.d.ts} +3 -3
- package/dist/models/index.d.ts +5 -5
- package/dist/models/index.js +28 -5
- package/dist/models/index.js.map +1 -1
- package/dist/{models-registry-C3a-2-Yd.d.ts → models-registry-DP6pGHet.d.ts} +1 -1
- package/dist/{multi-agent-coordinator-CJSpTe5O.d.ts → multi-agent-coordinator-BvbdNQ14.d.ts} +1 -1
- package/dist/{null-fleet-bus-QVshIsDx.d.ts → null-fleet-bus-BxTfXBKo.d.ts} +6 -6
- package/dist/observability/index.d.ts +2 -2
- package/dist/{parallel-eternal-engine-D9y5Pkcc.d.ts → parallel-eternal-engine-Cf-GTegR.d.ts} +9 -9
- package/dist/{path-resolver-CnQ8SIfh.d.ts → path-resolver-DztfnFcv.d.ts} +3 -3
- package/dist/{permission-CvYQNUqZ.d.ts → permission-CC7XFYWG.d.ts} +1 -1
- package/dist/{permission-policy-D5Ss8j4B.d.ts → permission-policy-cYR4RJmw.d.ts} +2 -2
- package/dist/{pipeline-l_zzFRh3.d.ts → pipeline-sNIkhXeB.d.ts} +2 -2
- package/dist/{plan-templates-NtPgyeJA.d.ts → plan-templates-DYiKFmEb.d.ts} +11 -5
- package/dist/{provider-model-resolve-d5poT5y0.d.ts → provider-model-resolve-dYAbTs_i.d.ts} +3 -3
- package/dist/{provider-runner-gkctlQV_.d.ts → provider-runner-Dw8x0F7u.d.ts} +3 -3
- package/dist/{retry-policy-CtFhfwa8.d.ts → retry-policy-BV7nzeAd.d.ts} +1 -1
- package/dist/sdd/index.d.ts +8 -8
- package/dist/sdd/index.js +2 -0
- package/dist/sdd/index.js.map +1 -1
- package/dist/{secret-vault-BLsVmTIK.d.ts → secret-vault-eMBKfheR.d.ts} +9 -1
- package/dist/security/index.d.ts +5 -5
- package/dist/security/index.js +137 -10
- package/dist/security/index.js.map +1 -1
- package/dist/{selector-CXl2_y9W.d.ts → selector-C4ORTOid.d.ts} +1 -1
- package/dist/{session-event-bridge-Ccud20CC.d.ts → session-event-bridge-CeNpUL9w.d.ts} +1 -1
- package/dist/{session-reader-ZeXQmsmE.d.ts → session-reader-BepLSnGL.d.ts} +1 -1
- package/dist/storage/index.d.ts +45 -13
- package/dist/storage/index.js +374 -113
- package/dist/storage/index.js.map +1 -1
- package/dist/tools/index.d.ts +2 -2
- package/dist/tools/index.js +9 -2
- package/dist/tools/index.js.map +1 -1
- package/dist/types/index.d.ts +19 -19
- package/dist/types/index.js +202 -41
- package/dist/types/index.js.map +1 -1
- package/dist/utils/index.d.ts +17 -4
- package/dist/utils/index.js +48 -9
- package/dist/utils/index.js.map +1 -1
- package/package.json +1 -1
package/dist/types/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { randomBytes, createCipheriv, createDecipheriv, randomUUID } from 'crypto';
|
|
1
|
+
import { randomBytes, createCipheriv, createDecipheriv, randomUUID, scryptSync } from 'crypto';
|
|
2
2
|
import * as fs from 'fs/promises';
|
|
3
3
|
import * as path6 from 'path';
|
|
4
4
|
import * as os from 'os';
|
|
@@ -703,18 +703,20 @@ function calState(key) {
|
|
|
703
703
|
return state;
|
|
704
704
|
}
|
|
705
705
|
var ESTIMATE_CACHE = /* @__PURE__ */ new Map();
|
|
706
|
+
var _estimateCacheOrder = [];
|
|
706
707
|
var ESTIMATE_CACHE_MAX_SIZE = 5e4;
|
|
707
708
|
function getCachedEstimate(key, compute) {
|
|
708
709
|
const existing = ESTIMATE_CACHE.get(key);
|
|
709
710
|
if (existing !== void 0) return existing;
|
|
710
711
|
if (ESTIMATE_CACHE.size >= ESTIMATE_CACHE_MAX_SIZE) {
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
ESTIMATE_CACHE.delete(
|
|
712
|
+
while (ESTIMATE_CACHE.size > Math.floor(ESTIMATE_CACHE_MAX_SIZE / 2)) {
|
|
713
|
+
const oldest = _estimateCacheOrder.shift();
|
|
714
|
+
if (oldest !== void 0) ESTIMATE_CACHE.delete(oldest);
|
|
714
715
|
}
|
|
715
716
|
}
|
|
716
717
|
const estimate = compute(key);
|
|
717
718
|
ESTIMATE_CACHE.set(key, estimate);
|
|
719
|
+
_estimateCacheOrder.push(key);
|
|
718
720
|
return estimate;
|
|
719
721
|
}
|
|
720
722
|
function estimateToolInputTokens(input) {
|
|
@@ -1864,6 +1866,83 @@ var ALGO = "aes-256-gcm";
|
|
|
1864
1866
|
var KEY_FILE_MODE = 384;
|
|
1865
1867
|
var KEY_FILE_MAGIC = Buffer.from("WSKV", "ascii");
|
|
1866
1868
|
var VERSIONED_KEY_FILE_SIZE = KEY_FILE_MAGIC.length + 1 + KEY_BYTES;
|
|
1869
|
+
var KEK_MAGIC = Buffer.from("WSKW", "ascii");
|
|
1870
|
+
var KEK_SALT_BYTES = 16;
|
|
1871
|
+
var WRAPPED_KEY_FILE_SIZE = KEK_MAGIC.length + 1 + KEK_SALT_BYTES + IV_BYTES + TAG_BYTES + KEY_BYTES;
|
|
1872
|
+
var SCRYPT_N = 1 << 15;
|
|
1873
|
+
var SCRYPT_R = 8;
|
|
1874
|
+
var SCRYPT_P = 1;
|
|
1875
|
+
var SCRYPT_MAXMEM = 64 * 1024 * 1024;
|
|
1876
|
+
function getVaultPassphrase() {
|
|
1877
|
+
const v = process.env["WRONGSTACK_VAULT_PASSPHRASE"];
|
|
1878
|
+
return v && v.length > 0 ? v : void 0;
|
|
1879
|
+
}
|
|
1880
|
+
function isWrappedKeyFile(buf) {
|
|
1881
|
+
return buf.length === WRAPPED_KEY_FILE_SIZE && buf.subarray(0, KEK_MAGIC.length).equals(KEK_MAGIC);
|
|
1882
|
+
}
|
|
1883
|
+
function deriveKEK(passphrase, salt) {
|
|
1884
|
+
return scryptSync(passphrase, salt, KEY_BYTES, {
|
|
1885
|
+
N: SCRYPT_N,
|
|
1886
|
+
r: SCRYPT_R,
|
|
1887
|
+
p: SCRYPT_P,
|
|
1888
|
+
maxmem: SCRYPT_MAXMEM
|
|
1889
|
+
});
|
|
1890
|
+
}
|
|
1891
|
+
function wrapDataKey(dataKey, keyVersion, passphrase) {
|
|
1892
|
+
const salt = randomBytes(KEK_SALT_BYTES);
|
|
1893
|
+
const iv = randomBytes(IV_BYTES);
|
|
1894
|
+
const kek = deriveKEK(passphrase, salt);
|
|
1895
|
+
const cipher = createCipheriv(ALGO, kek, iv);
|
|
1896
|
+
const ct = Buffer.concat([cipher.update(dataKey), cipher.final()]);
|
|
1897
|
+
const tag = cipher.getAuthTag();
|
|
1898
|
+
const out = Buffer.alloc(WRAPPED_KEY_FILE_SIZE);
|
|
1899
|
+
let off = 0;
|
|
1900
|
+
KEK_MAGIC.copy(out, off);
|
|
1901
|
+
off += KEK_MAGIC.length;
|
|
1902
|
+
out[off] = keyVersion & 255;
|
|
1903
|
+
off += 1;
|
|
1904
|
+
salt.copy(out, off);
|
|
1905
|
+
off += KEK_SALT_BYTES;
|
|
1906
|
+
iv.copy(out, off);
|
|
1907
|
+
off += IV_BYTES;
|
|
1908
|
+
tag.copy(out, off);
|
|
1909
|
+
off += TAG_BYTES;
|
|
1910
|
+
ct.copy(out, off);
|
|
1911
|
+
return out;
|
|
1912
|
+
}
|
|
1913
|
+
function unwrapDataKey(buf, keyFile) {
|
|
1914
|
+
const passphrase = getVaultPassphrase();
|
|
1915
|
+
if (!passphrase) {
|
|
1916
|
+
throw new ConfigError({
|
|
1917
|
+
message: `SecretVault: key file ${keyFile} is passphrase-protected \u2014 set the WRONGSTACK_VAULT_PASSPHRASE environment variable to unlock it.`,
|
|
1918
|
+
code: ERROR_CODES.CONFIG_INVALID,
|
|
1919
|
+
context: { keyFile }
|
|
1920
|
+
});
|
|
1921
|
+
}
|
|
1922
|
+
let off = KEK_MAGIC.length;
|
|
1923
|
+
const version = buf[off];
|
|
1924
|
+
off += 1;
|
|
1925
|
+
const salt = buf.subarray(off, off + KEK_SALT_BYTES);
|
|
1926
|
+
off += KEK_SALT_BYTES;
|
|
1927
|
+
const iv = buf.subarray(off, off + IV_BYTES);
|
|
1928
|
+
off += IV_BYTES;
|
|
1929
|
+
const tag = buf.subarray(off, off + TAG_BYTES);
|
|
1930
|
+
off += TAG_BYTES;
|
|
1931
|
+
const ct = buf.subarray(off, off + KEY_BYTES);
|
|
1932
|
+
const kek = deriveKEK(passphrase, salt);
|
|
1933
|
+
const decipher = createDecipheriv(ALGO, kek, iv);
|
|
1934
|
+
decipher.setAuthTag(tag);
|
|
1935
|
+
try {
|
|
1936
|
+
const key = Buffer.concat([decipher.update(ct), decipher.final()]);
|
|
1937
|
+
return { key: Buffer.from(key), version };
|
|
1938
|
+
} catch {
|
|
1939
|
+
throw new ConfigError({
|
|
1940
|
+
message: `SecretVault: failed to unlock key file ${keyFile} \u2014 wrong WRONGSTACK_VAULT_PASSPHRASE (key unwrap authentication failed).`,
|
|
1941
|
+
code: ERROR_CODES.CONFIG_INVALID,
|
|
1942
|
+
context: { keyFile }
|
|
1943
|
+
});
|
|
1944
|
+
}
|
|
1945
|
+
}
|
|
1867
1946
|
function checkKeyFilePermissions(keyFile) {
|
|
1868
1947
|
if (process.platform === "win32") return;
|
|
1869
1948
|
try {
|
|
@@ -1956,25 +2035,56 @@ var DefaultSecretVault = class {
|
|
|
1956
2035
|
const oldVersion = this._keyVersion;
|
|
1957
2036
|
const newKey = randomBytes(KEY_BYTES);
|
|
1958
2037
|
const newVersion = oldVersion + 1;
|
|
1959
|
-
const keyFileBuf = Buffer.alloc(VERSIONED_KEY_FILE_SIZE);
|
|
1960
|
-
KEY_FILE_MAGIC.copy(keyFileBuf, 0);
|
|
1961
|
-
keyFileBuf[KEY_FILE_MAGIC.length] = newVersion;
|
|
1962
|
-
newKey.copy(keyFileBuf, KEY_FILE_MAGIC.length + 1);
|
|
1963
2038
|
fs2.mkdirSync(path6.dirname(this.keyFile), { recursive: true });
|
|
1964
|
-
|
|
2039
|
+
const passphrase = getVaultPassphrase();
|
|
2040
|
+
if (passphrase) {
|
|
2041
|
+
fs2.writeFileSync(this.keyFile, wrapDataKey(newKey, newVersion, passphrase), { mode: 384 });
|
|
2042
|
+
} else {
|
|
2043
|
+
const keyFileBuf = Buffer.alloc(VERSIONED_KEY_FILE_SIZE);
|
|
2044
|
+
KEY_FILE_MAGIC.copy(keyFileBuf, 0);
|
|
2045
|
+
keyFileBuf[KEY_FILE_MAGIC.length] = newVersion;
|
|
2046
|
+
newKey.copy(keyFileBuf, KEY_FILE_MAGIC.length + 1);
|
|
2047
|
+
fs2.writeFileSync(this.keyFile, keyFileBuf, { mode: 384 });
|
|
2048
|
+
}
|
|
1965
2049
|
checkKeyFilePermissions(this.keyFile);
|
|
1966
2050
|
this.key = newKey;
|
|
1967
2051
|
this._keyVersion = newVersion;
|
|
1968
2052
|
return { oldVersion, newVersion };
|
|
1969
2053
|
}
|
|
2054
|
+
/**
|
|
2055
|
+
* If WRONGSTACK_VAULT_PASSPHRASE is set but the key on disk is still stored
|
|
2056
|
+
* unwrapped (legacy v1 / versioned v2), re-write it in passphrase-wrapped (v3)
|
|
2057
|
+
* form. The data key is preserved, so all existing ciphertext keeps
|
|
2058
|
+
* decrypting. Best-effort: a write failure leaves the working unwrapped file
|
|
2059
|
+
* in place and is not fatal to load.
|
|
2060
|
+
*/
|
|
2061
|
+
migrateToWrappedIfPassphrase() {
|
|
2062
|
+
const passphrase = getVaultPassphrase();
|
|
2063
|
+
if (!passphrase || !this.key) return;
|
|
2064
|
+
try {
|
|
2065
|
+
fs2.writeFileSync(this.keyFile, wrapDataKey(this.key, this._keyVersion, passphrase), {
|
|
2066
|
+
mode: 384
|
|
2067
|
+
});
|
|
2068
|
+
checkKeyFilePermissions(this.keyFile);
|
|
2069
|
+
} catch {
|
|
2070
|
+
}
|
|
2071
|
+
}
|
|
1970
2072
|
loadOrCreateKey() {
|
|
1971
2073
|
if (this.key) return this.key;
|
|
1972
2074
|
try {
|
|
1973
2075
|
const buf = fs2.readFileSync(this.keyFile);
|
|
2076
|
+
if (isWrappedKeyFile(buf)) {
|
|
2077
|
+
const { key: key2, version } = unwrapDataKey(buf, this.keyFile);
|
|
2078
|
+
this.key = key2;
|
|
2079
|
+
this._keyVersion = version;
|
|
2080
|
+
checkKeyFilePermissions(this.keyFile);
|
|
2081
|
+
return this.key;
|
|
2082
|
+
}
|
|
1974
2083
|
if (buf.length === KEY_BYTES) {
|
|
1975
2084
|
this.key = buf;
|
|
1976
2085
|
this._keyVersion = 1;
|
|
1977
2086
|
checkKeyFilePermissions(this.keyFile);
|
|
2087
|
+
this.migrateToWrappedIfPassphrase();
|
|
1978
2088
|
return this.key;
|
|
1979
2089
|
}
|
|
1980
2090
|
if (buf.length === VERSIONED_KEY_FILE_SIZE) {
|
|
@@ -1998,6 +2108,7 @@ var DefaultSecretVault = class {
|
|
|
1998
2108
|
this.key = Buffer.from(key2);
|
|
1999
2109
|
this._keyVersion = version;
|
|
2000
2110
|
checkKeyFilePermissions(this.keyFile);
|
|
2111
|
+
this.migrateToWrappedIfPassphrase();
|
|
2001
2112
|
return this.key;
|
|
2002
2113
|
}
|
|
2003
2114
|
throw new ConfigError({
|
|
@@ -2010,11 +2121,20 @@ var DefaultSecretVault = class {
|
|
|
2010
2121
|
}
|
|
2011
2122
|
fs2.mkdirSync(path6.dirname(this.keyFile), { recursive: true });
|
|
2012
2123
|
const key = randomBytes(KEY_BYTES);
|
|
2124
|
+
const passphrase = getVaultPassphrase();
|
|
2125
|
+
const initialBytes = passphrase ? wrapDataKey(key, 1, passphrase) : key;
|
|
2013
2126
|
try {
|
|
2014
|
-
fs2.writeFileSync(this.keyFile,
|
|
2127
|
+
fs2.writeFileSync(this.keyFile, initialBytes, { mode: 384, flag: "wx" });
|
|
2015
2128
|
} catch (err) {
|
|
2016
2129
|
if (err.code !== "EEXIST") throw err;
|
|
2017
2130
|
const buf = fs2.readFileSync(this.keyFile);
|
|
2131
|
+
if (isWrappedKeyFile(buf)) {
|
|
2132
|
+
const { key: winnerKey, version } = unwrapDataKey(buf, this.keyFile);
|
|
2133
|
+
this.key = winnerKey;
|
|
2134
|
+
this._keyVersion = version;
|
|
2135
|
+
checkKeyFilePermissions(this.keyFile);
|
|
2136
|
+
return this.key;
|
|
2137
|
+
}
|
|
2018
2138
|
if (buf.length === KEY_BYTES) {
|
|
2019
2139
|
this.key = buf;
|
|
2020
2140
|
this._keyVersion = 1;
|
|
@@ -2618,17 +2738,9 @@ function findPreserveStart(messages, preserveK) {
|
|
|
2618
2738
|
const prev = messages[preserveStart - 1];
|
|
2619
2739
|
if (!first || !prev || first.role !== "user" || prev.role !== "assistant") break;
|
|
2620
2740
|
if (typeof first.content === "string" || typeof prev.content === "string") break;
|
|
2621
|
-
const
|
|
2622
|
-
|
|
2623
|
-
|
|
2624
|
-
if (block.type === "tool_result") resultIds.add(block.tool_use_id);
|
|
2625
|
-
}
|
|
2626
|
-
if (resultIds.size === 0) break;
|
|
2627
|
-
const hasMatchingUse = prev.content.some((block) => {
|
|
2628
|
-
pairRepairInnerIterations++;
|
|
2629
|
-
return block.type === "tool_use" && resultIds.has(block.id);
|
|
2630
|
-
});
|
|
2631
|
-
if (!hasMatchingUse) break;
|
|
2741
|
+
const pairCheck = hasMatchingToolPair(first.content, prev.content);
|
|
2742
|
+
pairRepairInnerIterations += pairCheck.iterations;
|
|
2743
|
+
if (!pairCheck.matched) break;
|
|
2632
2744
|
preserveStart--;
|
|
2633
2745
|
}
|
|
2634
2746
|
if (compactionDebugEnabled()) {
|
|
@@ -2647,9 +2759,34 @@ function findPreserveStart(messages, preserveK) {
|
|
|
2647
2759
|
}
|
|
2648
2760
|
return preserveStart;
|
|
2649
2761
|
}
|
|
2762
|
+
function hasMatchingToolPair(resultContent, useContent) {
|
|
2763
|
+
let iterations = 0;
|
|
2764
|
+
let firstResultId;
|
|
2765
|
+
let resultIds;
|
|
2766
|
+
for (const block of resultContent) {
|
|
2767
|
+
iterations++;
|
|
2768
|
+
if (block.type !== "tool_result") continue;
|
|
2769
|
+
if (firstResultId === void 0) {
|
|
2770
|
+
firstResultId = block.tool_use_id;
|
|
2771
|
+
} else {
|
|
2772
|
+
resultIds ??= /* @__PURE__ */ new Set([firstResultId]);
|
|
2773
|
+
resultIds.add(block.tool_use_id);
|
|
2774
|
+
}
|
|
2775
|
+
}
|
|
2776
|
+
if (firstResultId === void 0) return { matched: false, iterations };
|
|
2777
|
+
for (const block of useContent) {
|
|
2778
|
+
iterations++;
|
|
2779
|
+
if (block.type !== "tool_use") continue;
|
|
2780
|
+
if (resultIds ? resultIds.has(block.id) : block.id === firstResultId) {
|
|
2781
|
+
return { matched: true, iterations };
|
|
2782
|
+
}
|
|
2783
|
+
}
|
|
2784
|
+
return { matched: false, iterations };
|
|
2785
|
+
}
|
|
2650
2786
|
function eliseOldToolResults(messages, opts) {
|
|
2651
2787
|
const preserveStart = findPreserveStart(messages, opts.preserveK);
|
|
2652
2788
|
let hasOversized = false;
|
|
2789
|
+
let firstOversizedIndex = -1;
|
|
2653
2790
|
let fastPathIterations = 0;
|
|
2654
2791
|
let fastPathInnerIterations = 0;
|
|
2655
2792
|
for (let i = 0; i < preserveStart && !hasOversized; i++) {
|
|
@@ -2661,6 +2798,7 @@ function eliseOldToolResults(messages, opts) {
|
|
|
2661
2798
|
const oversized = b.type === "tool_result" && estimateToolResultTokens(b.content) >= opts.eliseThreshold || b.type === "tool_use" && estimateToolInputTokens(b.input) >= opts.eliseThreshold;
|
|
2662
2799
|
if (oversized) {
|
|
2663
2800
|
hasOversized = true;
|
|
2801
|
+
firstOversizedIndex = i;
|
|
2664
2802
|
break;
|
|
2665
2803
|
}
|
|
2666
2804
|
}
|
|
@@ -2683,26 +2821,29 @@ function eliseOldToolResults(messages, opts) {
|
|
|
2683
2821
|
let changed = false;
|
|
2684
2822
|
let fullPassIterations = 0;
|
|
2685
2823
|
let fullPassInnerIterations = 0;
|
|
2686
|
-
|
|
2687
|
-
for (let i =
|
|
2824
|
+
let next;
|
|
2825
|
+
for (let i = firstOversizedIndex; i < preserveStart; i++) {
|
|
2688
2826
|
fullPassIterations++;
|
|
2689
2827
|
const msg = messages[i];
|
|
2690
|
-
if (
|
|
2691
|
-
next[i] = msg;
|
|
2692
|
-
continue;
|
|
2693
|
-
}
|
|
2828
|
+
if (!msg || !Array.isArray(msg.content)) continue;
|
|
2694
2829
|
const original = msg.content;
|
|
2695
|
-
|
|
2830
|
+
let newContent;
|
|
2831
|
+
for (let idx = 0; idx < original.length; idx++) {
|
|
2832
|
+
fullPassInnerIterations++;
|
|
2833
|
+
const b = original[idx];
|
|
2834
|
+
if (!b) continue;
|
|
2696
2835
|
if (b.type === "tool_use") {
|
|
2697
2836
|
const tokens2 = estimateToolInputTokens(b.input);
|
|
2698
|
-
if (tokens2 < opts.eliseThreshold)
|
|
2837
|
+
if (tokens2 < opts.eliseThreshold) continue;
|
|
2699
2838
|
const elidedInput = summarizeToolUseInputElision(b, tokens2);
|
|
2700
2839
|
saved += Math.max(0, tokens2 - estimateToolInputTokens(elidedInput));
|
|
2701
|
-
|
|
2840
|
+
newContent ??= original.slice();
|
|
2841
|
+
newContent[idx] = { ...b, input: elidedInput };
|
|
2842
|
+
continue;
|
|
2702
2843
|
}
|
|
2703
|
-
if (b.type !== "tool_result")
|
|
2844
|
+
if (b.type !== "tool_result") continue;
|
|
2704
2845
|
const tokens = estimateToolResultTokens(b.content);
|
|
2705
|
-
if (tokens < opts.eliseThreshold)
|
|
2846
|
+
if (tokens < opts.eliseThreshold) continue;
|
|
2706
2847
|
saved += tokens;
|
|
2707
2848
|
const elided = {
|
|
2708
2849
|
type: "tool_result",
|
|
@@ -2710,15 +2851,14 @@ function eliseOldToolResults(messages, opts) {
|
|
|
2710
2851
|
content: summarizeToolResultElision(b, tokens),
|
|
2711
2852
|
is_error: b.is_error
|
|
2712
2853
|
};
|
|
2713
|
-
|
|
2714
|
-
|
|
2715
|
-
|
|
2716
|
-
|
|
2717
|
-
|
|
2854
|
+
newContent ??= original.slice();
|
|
2855
|
+
newContent[idx] = elided;
|
|
2856
|
+
}
|
|
2857
|
+
if (newContent) {
|
|
2858
|
+
next ??= messages.slice();
|
|
2718
2859
|
next[i] = { ...msg, content: newContent };
|
|
2719
2860
|
changed = true;
|
|
2720
2861
|
}
|
|
2721
|
-
fullPassInnerIterations += original.length;
|
|
2722
2862
|
if (compactionDebugEnabled()) {
|
|
2723
2863
|
const ratio = fullPassInnerIterations / fullPassIterations;
|
|
2724
2864
|
if (ratio > 10) {
|
|
@@ -2745,7 +2885,7 @@ function eliseOldToolResults(messages, opts) {
|
|
|
2745
2885
|
tokensSaved: saved,
|
|
2746
2886
|
changed
|
|
2747
2887
|
});
|
|
2748
|
-
return { messages: changed ? next : messages, saved, changed };
|
|
2888
|
+
return { messages: changed && next ? next : messages, saved, changed };
|
|
2749
2889
|
}
|
|
2750
2890
|
function summarizeToolUseInputElision(block, tokens) {
|
|
2751
2891
|
const fields = {};
|
|
@@ -3471,6 +3611,7 @@ var DefaultSecretScrubber = class {
|
|
|
3471
3611
|
}
|
|
3472
3612
|
};
|
|
3473
3613
|
var DEFAULT_URL = "https://models.dev/api.json";
|
|
3614
|
+
var ENV_URL_KEY = "WRONGSTACK_MODELS_DEV_URL";
|
|
3474
3615
|
var DEFAULT_TTL_SECONDS = 24 * 3600;
|
|
3475
3616
|
var DEFAULT_REFRESH_TIMEOUT_MS = 15e3;
|
|
3476
3617
|
var FAMILY_BY_NPM = {
|
|
@@ -3516,7 +3657,7 @@ var DefaultModelsRegistry = class {
|
|
|
3516
3657
|
overlayCacheFile;
|
|
3517
3658
|
constructor(opts) {
|
|
3518
3659
|
this.cacheFile = opts.cacheFile;
|
|
3519
|
-
this.url = opts.url ?? DEFAULT_URL;
|
|
3660
|
+
this.url = opts.url ?? process.env[ENV_URL_KEY] ?? DEFAULT_URL;
|
|
3520
3661
|
this.ttlMs = (opts.ttlSeconds ?? DEFAULT_TTL_SECONDS) * 1e3;
|
|
3521
3662
|
this.fetchImpl = opts.fetchImpl ?? fetch;
|
|
3522
3663
|
this.seed = opts.seed;
|
|
@@ -3561,6 +3702,10 @@ var DefaultModelsRegistry = class {
|
|
|
3561
3702
|
const cached = await this.readCacheAt(this.cacheFile);
|
|
3562
3703
|
if (cached && this.isWithinMaxStaleAge(cached.fetchedAt)) {
|
|
3563
3704
|
this.fetchedAt = new Date(cached.fetchedAt);
|
|
3705
|
+
const ageSeconds = Math.floor((Date.now() - this.fetchedAt.getTime()) / 1e3);
|
|
3706
|
+
console.warn(
|
|
3707
|
+
`ModelsRegistry: models.dev unavailable (${toErrorMessage(err)}); using stale cache from ${formatAge(ageSeconds)} ago. Run \`wstack models refresh\` to retry.`
|
|
3708
|
+
);
|
|
3564
3709
|
return cached.payload;
|
|
3565
3710
|
}
|
|
3566
3711
|
if (overlayAvailable) {
|
|
@@ -3646,7 +3791,13 @@ var DefaultModelsRegistry = class {
|
|
|
3646
3791
|
return json;
|
|
3647
3792
|
} catch {
|
|
3648
3793
|
const cached = await this.readCacheAt(this.overlayCacheFile);
|
|
3649
|
-
if (cached && this.isWithinMaxStaleAge(cached.fetchedAt))
|
|
3794
|
+
if (cached && this.isWithinMaxStaleAge(cached.fetchedAt)) {
|
|
3795
|
+
const ageSeconds = Math.floor((Date.now() - new Date(cached.fetchedAt).getTime()) / 1e3);
|
|
3796
|
+
console.warn(
|
|
3797
|
+
`ModelsRegistry: overlay unavailable; using stale overlay from ${formatAge(ageSeconds)} ago.`
|
|
3798
|
+
);
|
|
3799
|
+
return cached.payload;
|
|
3800
|
+
}
|
|
3650
3801
|
return void 0;
|
|
3651
3802
|
}
|
|
3652
3803
|
}
|
|
@@ -3743,6 +3894,16 @@ var DefaultModelsRegistry = class {
|
|
|
3743
3894
|
return path6.resolve(this.cacheFile);
|
|
3744
3895
|
}
|
|
3745
3896
|
};
|
|
3897
|
+
function formatAge(seconds) {
|
|
3898
|
+
if (seconds < 60) return "<1m";
|
|
3899
|
+
if (seconds < 3600) return `${Math.floor(seconds / 60)}m`;
|
|
3900
|
+
if (seconds < 86400) {
|
|
3901
|
+
const h = Math.floor(seconds / 3600);
|
|
3902
|
+
const m = Math.floor(seconds % 3600 / 60);
|
|
3903
|
+
return m > 0 ? `${h}h ${m}m` : `${h}h`;
|
|
3904
|
+
}
|
|
3905
|
+
return `${Math.floor(seconds / 86400)}d`;
|
|
3906
|
+
}
|
|
3746
3907
|
function hasEntries(payload) {
|
|
3747
3908
|
return payload !== void 0 && Object.keys(payload).length > 0;
|
|
3748
3909
|
}
|