@wrongstack/core 0.109.1 → 0.141.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-mOxbpFcg.d.ts → agent-bridge-r9y6gdn4.d.ts} +1 -1
- package/dist/{agent-subagent-runner-DukQLUcS.d.ts → agent-subagent-runner-1GeQE_L0.d.ts} +7 -8
- package/dist/{brain-Dfv4Y82E.d.ts → brain-Cp_3GIS2.d.ts} +14 -3
- package/dist/{compactor-DXLxLcmU.d.ts → compactor-BueGt7LG.d.ts} +9 -1
- package/dist/{config-BSU-6vah.d.ts → config-BaVThgnT.d.ts} +104 -3
- package/dist/{context-CNRYfhUv.d.ts → context-C7G_MtLV.d.ts} +38 -1
- package/dist/coordination/index.d.ts +12 -13
- package/dist/coordination/index.js +229 -17
- package/dist/coordination/index.js.map +1 -1
- package/dist/defaults/index.d.ts +26 -27
- package/dist/defaults/index.js +886 -721
- package/dist/defaults/index.js.map +1 -1
- package/dist/execution/index.d.ts +15 -16
- package/dist/execution/index.js +535 -322
- package/dist/execution/index.js.map +1 -1
- package/dist/extension/index.d.ts +6 -7
- package/dist/{goal-preamble-CI8lxeY1.d.ts → goal-preamble-iuIUTQwk.d.ts} +48 -18
- package/dist/{index-BWRN6wOb.d.ts → index-BZdezm3g.d.ts} +9 -10
- package/dist/{index-DIKEcfgC.d.ts → index-CPweVoFM.d.ts} +7 -6
- package/dist/index.d.ts +51 -52
- package/dist/index.js +752 -545
- package/dist/index.js.map +1 -1
- package/dist/infrastructure/index.d.ts +6 -7
- package/dist/infrastructure/index.js +64 -19
- package/dist/infrastructure/index.js.map +1 -1
- package/dist/kernel/index.d.ts +10 -11
- package/dist/kernel/index.js.map +1 -1
- package/dist/llm-selector-CP72f1lC.d.ts +58 -0
- package/dist/{mcp-servers-CXCsANdY.d.ts → mcp-servers-Bl5LTvQg.d.ts} +3 -3
- package/dist/{mode-ARA3HrkY.d.ts → mode-CZlO9iU1.d.ts} +1 -1
- package/dist/models/index.d.ts +157 -53
- package/dist/models/index.js +475 -20
- package/dist/models/index.js.map +1 -1
- package/dist/{models-registry-DU64QxQa.d.ts → models-registry-D90K9UnM.d.ts} +1 -1
- package/dist/{multi-agent-coordinator-51LvnXkD.d.ts → multi-agent-coordinator-QWEzJDlm.d.ts} +1 -1
- package/dist/{null-fleet-bus-D09hMzFQ.d.ts → null-fleet-bus-BUyfqh23.d.ts} +13 -10
- package/dist/observability/index.d.ts +2 -2
- package/dist/{parallel-eternal-engine-B2CbsKpc.d.ts → parallel-eternal-engine-Dj2SYzha.d.ts} +24 -11
- package/dist/{path-resolver-DDJiMAtX.d.ts → path-resolver-DRjQBkoO.d.ts} +3 -3
- package/dist/{permission-BDv7z0mk.d.ts → permission-B7nKnEvQ.d.ts} +1 -1
- package/dist/{permission-policy-dF74EpDp.d.ts → permission-policy-8-6zBmfA.d.ts} +2 -13
- package/dist/{pipeline-BqiA_UMr.d.ts → pipeline-BG7UgbDc.d.ts} +2 -2
- package/dist/{plan-templates-BdDxl9cI.d.ts → plan-templates-CkKNPU3I.d.ts} +6 -6
- package/dist/{provider-runner-BUunikwY.d.ts → provider-runner-BNpuIyOL.d.ts} +3 -3
- package/dist/{retry-policy-BcmuT_V0.d.ts → retry-policy-rutAfVeR.d.ts} +1 -1
- package/dist/sdd/index.d.ts +8 -9
- package/dist/sdd/index.js +208 -1
- package/dist/sdd/index.js.map +1 -1
- package/dist/{secret-vault-DrOhc2i5.d.ts → secret-vault-BTcC_T5v.d.ts} +3 -2
- package/dist/security/index.d.ts +5 -7
- package/dist/security/index.js +4 -35
- package/dist/security/index.js.map +1 -1
- package/dist/{selector-C7wcdqMA.d.ts → selector-4vDFZKt3.d.ts} +1 -1
- package/dist/{session-event-bridge-BpJ5trO9.d.ts → session-event-bridge-DWlvglC2.d.ts} +2 -2
- package/dist/{session-reader-DDz1Ek4V.d.ts → session-reader-BAtCxdaw.d.ts} +1 -1
- package/dist/storage/index.d.ts +14 -15
- package/dist/storage/index.js +140 -134
- package/dist/storage/index.js.map +1 -1
- package/dist/types/index.d.ts +19 -20
- package/dist/types/index.js +186 -102
- package/dist/types/index.js.map +1 -1
- package/dist/utils/index.d.ts +38 -15
- package/dist/utils/index.js +62 -33
- package/dist/utils/index.js.map +1 -1
- package/dist/{wstack-paths-_lqjzErq.d.ts → wstack-paths-DD50Omgn.d.ts} +3 -0
- package/package.json +2 -2
- package/dist/models-registry-B6_KfS65.d.ts +0 -95
package/dist/index.js
CHANGED
|
@@ -1114,6 +1114,39 @@ function describeStatus(status, type) {
|
|
|
1114
1114
|
function truncate(s, n) {
|
|
1115
1115
|
return s.length <= n ? s : `${s.slice(0, n - 1)}\u2026`;
|
|
1116
1116
|
}
|
|
1117
|
+
var StreamHangError = class extends ProviderError {
|
|
1118
|
+
/** Name of the provider that hung, e.g. "zai", "anthropic". */
|
|
1119
|
+
hungProviderId;
|
|
1120
|
+
/** Model that was being called when the hang occurred. */
|
|
1121
|
+
hungModel;
|
|
1122
|
+
/** How long (ms) we waited for the next chunk before declaring a hang. */
|
|
1123
|
+
hangTimeoutMs;
|
|
1124
|
+
/** How many bytes were received before the hang. */
|
|
1125
|
+
bytesReceived;
|
|
1126
|
+
/** Elapsed time (ms) from the start of the stream until the hang. */
|
|
1127
|
+
elapsedMs;
|
|
1128
|
+
constructor(opts) {
|
|
1129
|
+
super(
|
|
1130
|
+
`Stream hang: ${opts.providerId}/${opts.model} \u2014 no data for ${opts.hangTimeoutMs}ms after ${opts.bytesReceived} bytes (${opts.elapsedMs}ms elapsed)`,
|
|
1131
|
+
599,
|
|
1132
|
+
true,
|
|
1133
|
+
// always retryable
|
|
1134
|
+
opts.providerId,
|
|
1135
|
+
{
|
|
1136
|
+
body: {
|
|
1137
|
+
message: `Stream stalled after ${opts.elapsedMs}ms, ${opts.bytesReceived} bytes received`
|
|
1138
|
+
},
|
|
1139
|
+
cause: opts.cause
|
|
1140
|
+
}
|
|
1141
|
+
);
|
|
1142
|
+
this.name = "StreamHangError";
|
|
1143
|
+
this.hungProviderId = opts.providerId;
|
|
1144
|
+
this.hungModel = opts.model;
|
|
1145
|
+
this.hangTimeoutMs = opts.hangTimeoutMs;
|
|
1146
|
+
this.bytesReceived = opts.bytesReceived;
|
|
1147
|
+
this.elapsedMs = opts.elapsedMs;
|
|
1148
|
+
}
|
|
1149
|
+
};
|
|
1117
1150
|
function providerStatusToCode(status, type) {
|
|
1118
1151
|
if (status === 0) return ERROR_CODES.PROVIDER_NETWORK_ERROR;
|
|
1119
1152
|
if (type === "rate_limit_error" || status === 429) return ERROR_CODES.PROVIDER_RATE_LIMITED;
|
|
@@ -1728,16 +1761,17 @@ function expectDefined(value, label) {
|
|
|
1728
1761
|
|
|
1729
1762
|
// src/utils/token-estimate.ts
|
|
1730
1763
|
var RoughTokenEstimate = (text, charsPerToken = 3.5) => Math.max(1, Math.ceil(text.length / charsPerToken));
|
|
1731
|
-
var
|
|
1732
|
-
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
|
|
1739
|
-
|
|
1740
|
-
|
|
1764
|
+
var CAL_ALPHA = 0.3;
|
|
1765
|
+
var CALIBRATION_GLOBAL_KEY = "__global__";
|
|
1766
|
+
var _cals = /* @__PURE__ */ new Map();
|
|
1767
|
+
function calState(key) {
|
|
1768
|
+
let state = _cals.get(key);
|
|
1769
|
+
if (!state) {
|
|
1770
|
+
state = { ratio: 1, count: 0, prevEst: 0 };
|
|
1771
|
+
_cals.set(key, state);
|
|
1772
|
+
}
|
|
1773
|
+
return state;
|
|
1774
|
+
}
|
|
1741
1775
|
var MIN_SAMPLES_FOR_CALIBRATION = 3;
|
|
1742
1776
|
var ESTIMATE_CACHE = /* @__PURE__ */ new Map();
|
|
1743
1777
|
var ESTIMATE_CACHE_MAX_SIZE = 1e4;
|
|
@@ -1770,10 +1804,25 @@ function estimateToolResultTokens(content) {
|
|
|
1770
1804
|
function estimateTextTokens(text) {
|
|
1771
1805
|
return RoughTokenEstimate(text);
|
|
1772
1806
|
}
|
|
1807
|
+
function estimateMessageTokens(messages) {
|
|
1808
|
+
let total = 0;
|
|
1809
|
+
for (const m of messages) {
|
|
1810
|
+
if (typeof m.content === "string") {
|
|
1811
|
+
total += estimateTextTokens(m.content);
|
|
1812
|
+
} else {
|
|
1813
|
+
for (const b of m.content) {
|
|
1814
|
+
if (b.type === "text") total += estimateTextTokens(b.text);
|
|
1815
|
+
else if (b.type === "tool_use") total += estimateToolInputTokens(b.input);
|
|
1816
|
+
else if (b.type === "tool_result") total += estimateToolResultTokens(b.content);
|
|
1817
|
+
}
|
|
1818
|
+
}
|
|
1819
|
+
}
|
|
1820
|
+
return total;
|
|
1821
|
+
}
|
|
1773
1822
|
function estimateToolDefTokens(tool) {
|
|
1774
1823
|
return RoughTokenEstimate(tool.name) + RoughTokenEstimate(tool.description ?? "") + RoughTokenEstimate(JSON.stringify(tool.inputSchema));
|
|
1775
1824
|
}
|
|
1776
|
-
function estimateRequestTokens(messages, systemPrompt, tools) {
|
|
1825
|
+
function estimateRequestTokens(messages, systemPrompt, tools, calibrationKey = CALIBRATION_GLOBAL_KEY) {
|
|
1777
1826
|
let messagesTokens = 0;
|
|
1778
1827
|
if (typeof messages === "string") {
|
|
1779
1828
|
messagesTokens = RoughTokenEstimate(messages);
|
|
@@ -1812,7 +1861,7 @@ function estimateRequestTokens(messages, systemPrompt, tools) {
|
|
|
1812
1861
|
toolsTokens += estimateToolDefTokens(t2);
|
|
1813
1862
|
}
|
|
1814
1863
|
const total = messagesTokens + systemTokens + toolsTokens;
|
|
1815
|
-
|
|
1864
|
+
calState(calibrationKey).prevEst = total;
|
|
1816
1865
|
return {
|
|
1817
1866
|
messages: messagesTokens,
|
|
1818
1867
|
systemPrompt: systemTokens,
|
|
@@ -1820,30 +1869,33 @@ function estimateRequestTokens(messages, systemPrompt, tools) {
|
|
|
1820
1869
|
total
|
|
1821
1870
|
};
|
|
1822
1871
|
}
|
|
1823
|
-
function recordActualUsage(actualInputTokens, estimatedInputTokens) {
|
|
1872
|
+
function recordActualUsage(actualInputTokens, estimatedInputTokens, calibrationKey = CALIBRATION_GLOBAL_KEY) {
|
|
1824
1873
|
if (actualInputTokens <= 0) return;
|
|
1825
|
-
const
|
|
1874
|
+
const cal = calState(calibrationKey);
|
|
1875
|
+
const est = estimatedInputTokens ?? cal.prevEst;
|
|
1826
1876
|
if (est <= 0) return;
|
|
1827
1877
|
const sampleRatio = actualInputTokens / est;
|
|
1828
|
-
if (
|
|
1829
|
-
|
|
1878
|
+
if (cal.count === 0) {
|
|
1879
|
+
cal.ratio = sampleRatio;
|
|
1830
1880
|
} else {
|
|
1831
|
-
|
|
1881
|
+
cal.ratio = CAL_ALPHA * sampleRatio + (1 - CAL_ALPHA) * cal.ratio;
|
|
1832
1882
|
}
|
|
1833
|
-
|
|
1834
|
-
|
|
1883
|
+
cal.ratio = Math.min(1.5, Math.max(0.5, cal.ratio));
|
|
1884
|
+
cal.count++;
|
|
1835
1885
|
}
|
|
1836
|
-
function getCalibrationState() {
|
|
1886
|
+
function getCalibrationState(calibrationKey = CALIBRATION_GLOBAL_KEY) {
|
|
1887
|
+
const cal = calState(calibrationKey);
|
|
1837
1888
|
return {
|
|
1838
|
-
ratio:
|
|
1839
|
-
count:
|
|
1840
|
-
calibrated:
|
|
1889
|
+
ratio: cal.ratio,
|
|
1890
|
+
count: cal.count,
|
|
1891
|
+
calibrated: cal.count >= MIN_SAMPLES_FOR_CALIBRATION
|
|
1841
1892
|
};
|
|
1842
1893
|
}
|
|
1843
|
-
function estimateRequestTokensCalibrated(messages, systemPrompt, tools) {
|
|
1844
|
-
const result = estimateRequestTokens(messages, systemPrompt, tools);
|
|
1845
|
-
|
|
1846
|
-
|
|
1894
|
+
function estimateRequestTokensCalibrated(messages, systemPrompt, tools, calibrationKey = CALIBRATION_GLOBAL_KEY) {
|
|
1895
|
+
const result = estimateRequestTokens(messages, systemPrompt, tools, calibrationKey);
|
|
1896
|
+
const cal = calState(calibrationKey);
|
|
1897
|
+
if (cal.count >= MIN_SAMPLES_FOR_CALIBRATION) {
|
|
1898
|
+
const safeRatio = Math.min(1.5, Math.max(0.5, cal.ratio));
|
|
1847
1899
|
return {
|
|
1848
1900
|
messages: Math.round(result.messages * safeRatio),
|
|
1849
1901
|
systemPrompt: Math.round(result.systemPrompt * safeRatio),
|
|
@@ -1853,10 +1905,12 @@ function estimateRequestTokensCalibrated(messages, systemPrompt, tools) {
|
|
|
1853
1905
|
}
|
|
1854
1906
|
return result;
|
|
1855
1907
|
}
|
|
1856
|
-
function resetCalibration() {
|
|
1857
|
-
|
|
1858
|
-
|
|
1859
|
-
|
|
1908
|
+
function resetCalibration(calibrationKey) {
|
|
1909
|
+
if (calibrationKey === void 0) {
|
|
1910
|
+
_cals.clear();
|
|
1911
|
+
return;
|
|
1912
|
+
}
|
|
1913
|
+
_cals.delete(calibrationKey);
|
|
1860
1914
|
}
|
|
1861
1915
|
|
|
1862
1916
|
// src/utils/message-invariants.ts
|
|
@@ -1951,34 +2005,144 @@ function isEmptyMessage(msg) {
|
|
|
1951
2005
|
return msg.content.length === 0;
|
|
1952
2006
|
}
|
|
1953
2007
|
|
|
2008
|
+
// src/execution/compaction-core.ts
|
|
2009
|
+
var estimateMessages = estimateMessageTokens;
|
|
2010
|
+
function hasTextContent(m) {
|
|
2011
|
+
if (typeof m.content === "string") return m.content.trim().length > 0;
|
|
2012
|
+
return m.content.some((b) => b.type === "text" && b.text.trim().length > 0);
|
|
2013
|
+
}
|
|
2014
|
+
function findPreserveStart(messages, preserveK) {
|
|
2015
|
+
let pairCount = 0;
|
|
2016
|
+
let preserveStart = messages.length;
|
|
2017
|
+
for (let i = messages.length - 1; i >= 0 && pairCount < preserveK; i--) {
|
|
2018
|
+
const m = messages[i];
|
|
2019
|
+
if (!m) continue;
|
|
2020
|
+
if (m.role === "user" || m.role === "assistant") {
|
|
2021
|
+
pairCount++;
|
|
2022
|
+
preserveStart = i;
|
|
2023
|
+
}
|
|
2024
|
+
}
|
|
2025
|
+
for (let i = preserveStart; i < messages.length; i++) {
|
|
2026
|
+
const m = messages[i];
|
|
2027
|
+
if (!m || typeof m.content === "string" || !Array.isArray(m.content)) continue;
|
|
2028
|
+
const hasToolUse2 = m.content.some((b) => b.type === "tool_use");
|
|
2029
|
+
if (hasToolUse2 && i + 1 < messages.length) {
|
|
2030
|
+
const next = messages[i + 1];
|
|
2031
|
+
if (next && next.role === "user" && typeof next.content !== "string" && Array.isArray(next.content) && next.content.some((b) => b.type === "tool_result")) {
|
|
2032
|
+
preserveStart = i + 1;
|
|
2033
|
+
}
|
|
2034
|
+
}
|
|
2035
|
+
}
|
|
2036
|
+
return preserveStart;
|
|
2037
|
+
}
|
|
2038
|
+
function eliseOldToolResults(messages, opts) {
|
|
2039
|
+
const preserveStart = findPreserveStart(messages, opts.preserveK);
|
|
2040
|
+
let saved = 0;
|
|
2041
|
+
let changed = false;
|
|
2042
|
+
const next = new Array(messages.length);
|
|
2043
|
+
for (let i = 0; i < messages.length; i++) {
|
|
2044
|
+
const msg = messages[i];
|
|
2045
|
+
if (i >= preserveStart || !msg || !Array.isArray(msg.content)) {
|
|
2046
|
+
next[i] = msg;
|
|
2047
|
+
continue;
|
|
2048
|
+
}
|
|
2049
|
+
const original = msg.content;
|
|
2050
|
+
const newContent = original.map((b) => {
|
|
2051
|
+
if (b.type !== "tool_result") return b;
|
|
2052
|
+
const tokens = estimateToolResultTokens(b.content);
|
|
2053
|
+
if (tokens < opts.eliseThreshold) return b;
|
|
2054
|
+
saved += tokens;
|
|
2055
|
+
const elided = {
|
|
2056
|
+
type: "tool_result",
|
|
2057
|
+
tool_use_id: b.tool_use_id,
|
|
2058
|
+
content: `[elided: ~${tokens} tokens]`,
|
|
2059
|
+
is_error: b.is_error
|
|
2060
|
+
};
|
|
2061
|
+
return elided;
|
|
2062
|
+
});
|
|
2063
|
+
if (newContent.every((b, idx) => b === original[idx])) {
|
|
2064
|
+
next[i] = msg;
|
|
2065
|
+
} else {
|
|
2066
|
+
next[i] = { ...msg, content: newContent };
|
|
2067
|
+
changed = true;
|
|
2068
|
+
}
|
|
2069
|
+
}
|
|
2070
|
+
return { messages: changed ? next : messages, saved, changed };
|
|
2071
|
+
}
|
|
2072
|
+
function buildLosslessDigest(messages) {
|
|
2073
|
+
const lines = [];
|
|
2074
|
+
for (const m of messages) {
|
|
2075
|
+
let text;
|
|
2076
|
+
let omitted = 0;
|
|
2077
|
+
if (typeof m.content === "string") {
|
|
2078
|
+
text = m.content;
|
|
2079
|
+
} else {
|
|
2080
|
+
const parts = [];
|
|
2081
|
+
for (const b of m.content) {
|
|
2082
|
+
if (isTextBlock(b)) parts.push(b.text);
|
|
2083
|
+
else if (b.type === "tool_use" || b.type === "tool_result") omitted++;
|
|
2084
|
+
}
|
|
2085
|
+
text = parts.join(" ");
|
|
2086
|
+
}
|
|
2087
|
+
if (text.trim().length === 0 && omitted === 0) continue;
|
|
2088
|
+
const marker = omitted > 0 ? ` [${omitted} tool call(s) omitted \u2014 see session log]` : "";
|
|
2089
|
+
lines.push(`[${m.role}]: ${text}${marker}`);
|
|
2090
|
+
}
|
|
2091
|
+
return lines.join("\n");
|
|
2092
|
+
}
|
|
2093
|
+
function findSafeBoundary(messages, from, to) {
|
|
2094
|
+
for (let i = to; i >= from; i--) {
|
|
2095
|
+
const m = messages[i];
|
|
2096
|
+
if (!m) continue;
|
|
2097
|
+
if (m.role === "user" && hasTextContent(m)) {
|
|
2098
|
+
return findExchangeStart(messages, i);
|
|
2099
|
+
}
|
|
2100
|
+
}
|
|
2101
|
+
return -1;
|
|
2102
|
+
}
|
|
2103
|
+
function findExchangeStart(messages, userIndex) {
|
|
2104
|
+
for (let i = userIndex - 1; i >= 0; i--) {
|
|
2105
|
+
const m = messages[i];
|
|
2106
|
+
if (!m) continue;
|
|
2107
|
+
if (m.role === "assistant") {
|
|
2108
|
+
const hasToolUse2 = Array.isArray(m.content) ? m.content.some((b) => b.type === "tool_use") : false;
|
|
2109
|
+
if (!hasToolUse2) return i + 1;
|
|
2110
|
+
} else if (m.role === "user") {
|
|
2111
|
+
return i;
|
|
2112
|
+
}
|
|
2113
|
+
}
|
|
2114
|
+
return 0;
|
|
2115
|
+
}
|
|
2116
|
+
|
|
1954
2117
|
// src/execution/compactor.ts
|
|
1955
2118
|
var HybridCompactor = class {
|
|
1956
2119
|
preserveK;
|
|
1957
2120
|
eliseThreshold;
|
|
1958
|
-
estimator;
|
|
1959
2121
|
constructor(opts = {}) {
|
|
1960
2122
|
this.preserveK = opts.preserveK ?? 5;
|
|
1961
2123
|
this.eliseThreshold = opts.eliseThreshold ?? 2e3;
|
|
1962
|
-
this.estimator = opts.estimator ?? estimateTextTokens;
|
|
1963
2124
|
}
|
|
1964
2125
|
async compact(ctx, opts = {}) {
|
|
1965
|
-
const beforeTokens =
|
|
2126
|
+
const beforeTokens = estimateMessages(ctx.messages);
|
|
1966
2127
|
const beforeFull = this.estimateFullRequest(ctx);
|
|
1967
2128
|
const reductions = [];
|
|
1968
2129
|
const policy = readContextWindowPolicy(ctx);
|
|
1969
2130
|
const preserveK = policy?.preserveK ?? this.preserveK;
|
|
1970
2131
|
const eliseThreshold = policy?.eliseThreshold ?? this.eliseThreshold;
|
|
1971
|
-
const
|
|
1972
|
-
if (
|
|
2132
|
+
const elide = eliseOldToolResults(ctx.messages, { preserveK, eliseThreshold });
|
|
2133
|
+
if (elide.changed) ctx.state.replaceMessages(elide.messages);
|
|
2134
|
+
if (elide.saved > 0) reductions.push({ phase: "elision", saved: elide.saved });
|
|
2135
|
+
let collapsedDigest;
|
|
1973
2136
|
if (opts.aggressive) {
|
|
1974
|
-
const
|
|
1975
|
-
if (
|
|
2137
|
+
const phase2 = this.collapseAncientTurns(ctx, preserveK);
|
|
2138
|
+
if (phase2.saved > 0) reductions.push({ phase: "summary", saved: phase2.saved });
|
|
2139
|
+
collapsedDigest = phase2.digest;
|
|
1976
2140
|
}
|
|
1977
2141
|
const repaired = repairToolUseAdjacency(ctx.messages);
|
|
1978
2142
|
if (repaired.report.changed) {
|
|
1979
2143
|
ctx.state.replaceMessages(repaired.messages);
|
|
1980
2144
|
}
|
|
1981
|
-
const afterTokens =
|
|
2145
|
+
const afterTokens = estimateMessages(ctx.messages);
|
|
1982
2146
|
const afterFull = this.estimateFullRequest(ctx);
|
|
1983
2147
|
return {
|
|
1984
2148
|
before: beforeTokens,
|
|
@@ -1986,6 +2150,7 @@ var HybridCompactor = class {
|
|
|
1986
2150
|
fullRequestTokensBefore: beforeFull,
|
|
1987
2151
|
fullRequestTokensAfter: afterFull,
|
|
1988
2152
|
reductions,
|
|
2153
|
+
collapsedDigest,
|
|
1989
2154
|
repaired: repaired.report.changed ? {
|
|
1990
2155
|
removedToolUses: repaired.report.removedToolUses,
|
|
1991
2156
|
removedToolResults: repaired.report.removedToolResults,
|
|
@@ -1998,72 +2163,23 @@ var HybridCompactor = class {
|
|
|
1998
2163
|
* This is the accurate figure for context-window pressure monitoring.
|
|
1999
2164
|
*/
|
|
2000
2165
|
estimateFullRequest(ctx) {
|
|
2001
|
-
|
|
2002
|
-
return breakdown.total;
|
|
2003
|
-
}
|
|
2004
|
-
eliseOldToolResults(ctx, preserveK = this.preserveK, eliseThreshold = this.eliseThreshold) {
|
|
2005
|
-
const messages = ctx.messages;
|
|
2006
|
-
let pairCount = 0;
|
|
2007
|
-
let preserveStart = messages.length;
|
|
2008
|
-
for (let i = messages.length - 1; i >= 0 && pairCount < preserveK; i--) {
|
|
2009
|
-
const m = messages[i];
|
|
2010
|
-
if (!m) continue;
|
|
2011
|
-
if (m.role === "user" || m.role === "assistant") {
|
|
2012
|
-
pairCount++;
|
|
2013
|
-
preserveStart = i;
|
|
2014
|
-
}
|
|
2015
|
-
}
|
|
2016
|
-
for (let i = preserveStart; i < messages.length; i++) {
|
|
2017
|
-
const m = messages[i];
|
|
2018
|
-
if (!m || typeof m.content === "string" || !Array.isArray(m.content)) continue;
|
|
2019
|
-
const hasToolUse2 = m.content.some((b) => b.type === "tool_use");
|
|
2020
|
-
if (hasToolUse2 && i + 1 < messages.length) {
|
|
2021
|
-
const next = messages[i + 1];
|
|
2022
|
-
if (next && next.role === "user" && typeof next.content !== "string" && Array.isArray(next.content) && next.content.some((b) => b.type === "tool_result")) {
|
|
2023
|
-
preserveStart = i + 1;
|
|
2024
|
-
}
|
|
2025
|
-
}
|
|
2026
|
-
}
|
|
2027
|
-
let saved = 0;
|
|
2028
|
-
let changed = false;
|
|
2029
|
-
const nextMessages = new Array(messages.length);
|
|
2030
|
-
for (let i = 0; i < messages.length; i++) {
|
|
2031
|
-
const msg = messages[i];
|
|
2032
|
-
if (i >= preserveStart) {
|
|
2033
|
-
nextMessages[i] = msg;
|
|
2034
|
-
continue;
|
|
2035
|
-
}
|
|
2036
|
-
if (!msg || !Array.isArray(msg.content)) {
|
|
2037
|
-
nextMessages[i] = msg;
|
|
2038
|
-
continue;
|
|
2039
|
-
}
|
|
2040
|
-
const newContent = msg.content.map((b) => {
|
|
2041
|
-
if (b.type !== "tool_result") return b;
|
|
2042
|
-
const tokens = estimateToolResultTokens(b.content);
|
|
2043
|
-
if (tokens < eliseThreshold) return b;
|
|
2044
|
-
saved += tokens;
|
|
2045
|
-
const elided = {
|
|
2046
|
-
type: "tool_result",
|
|
2047
|
-
tool_use_id: b.tool_use_id,
|
|
2048
|
-
content: `[elided: ~${tokens} tokens]`,
|
|
2049
|
-
is_error: b.is_error
|
|
2050
|
-
};
|
|
2051
|
-
return elided;
|
|
2052
|
-
});
|
|
2053
|
-
if (newContent.length === msg.content.length && newContent.every((b, idx) => b === msg.content[idx])) {
|
|
2054
|
-
nextMessages[i] = msg;
|
|
2055
|
-
} else {
|
|
2056
|
-
nextMessages[i] = { ...msg, content: newContent };
|
|
2057
|
-
changed = true;
|
|
2058
|
-
}
|
|
2059
|
-
}
|
|
2060
|
-
if (changed) ctx.state.replaceMessages(nextMessages);
|
|
2061
|
-
return saved;
|
|
2166
|
+
return estimateRequestTokens(ctx.messages, ctx.systemPrompt, ctx.tools ?? []).total;
|
|
2062
2167
|
}
|
|
2168
|
+
/**
|
|
2169
|
+
* Lossless rule-based collapse of ancient turns into a single digest message.
|
|
2170
|
+
*
|
|
2171
|
+
* Preserves ALL textual content of the collapsed range — user instructions,
|
|
2172
|
+
* assistant decisions/conclusions, and any prior digests (chained forward so
|
|
2173
|
+
* the digest stays lossless across repeated compactions). Only `tool_use` /
|
|
2174
|
+
* `tool_result` protocol blocks are dropped and replaced with a count marker;
|
|
2175
|
+
* their full payload already lives in the session log. No sub-LLM call.
|
|
2176
|
+
*
|
|
2177
|
+
* Returns the token savings and the digest text (for audit logging).
|
|
2178
|
+
*/
|
|
2063
2179
|
collapseAncientTurns(ctx, preserveK = this.preserveK) {
|
|
2064
2180
|
const messages = ctx.messages;
|
|
2065
2181
|
const cutTarget = Math.max(0, messages.length - preserveK * 2);
|
|
2066
|
-
if (cutTarget <= 0) return 0;
|
|
2182
|
+
if (cutTarget <= 0) return { saved: 0 };
|
|
2067
2183
|
let boundary = -1;
|
|
2068
2184
|
for (let i = cutTarget; i < messages.length; i++) {
|
|
2069
2185
|
const m = messages[i];
|
|
@@ -2073,34 +2189,20 @@ var HybridCompactor = class {
|
|
|
2073
2189
|
break;
|
|
2074
2190
|
}
|
|
2075
2191
|
}
|
|
2076
|
-
if (boundary <= 0) return 0;
|
|
2192
|
+
if (boundary <= 0) return { saved: 0 };
|
|
2077
2193
|
const removed = messages.slice(0, boundary);
|
|
2078
|
-
const removedTokens =
|
|
2079
|
-
const
|
|
2080
|
-
|
|
2081
|
-
|
|
2082
|
-
|
|
2083
|
-
|
|
2084
|
-
{ role: "assistant", content: "Continuing from compacted context." }
|
|
2085
|
-
];
|
|
2194
|
+
const removedTokens = estimateMessages(removed);
|
|
2195
|
+
const digest = buildLosslessDigest(removed) || `${removed.length} earlier turns (no textual content; tool I/O omitted \u2014 see session log)`;
|
|
2196
|
+
const summaryMsg = {
|
|
2197
|
+
role: "system",
|
|
2198
|
+
content: `[prior_turns_digest: ${digest}]`
|
|
2199
|
+
};
|
|
2086
2200
|
const tail = ctx.messages.slice(boundary);
|
|
2087
|
-
ctx.state.replaceMessages([
|
|
2088
|
-
return
|
|
2089
|
-
|
|
2090
|
-
|
|
2091
|
-
|
|
2092
|
-
for (const m of messages) {
|
|
2093
|
-
if (typeof m.content === "string") {
|
|
2094
|
-
total += this.estimator(m.content);
|
|
2095
|
-
} else {
|
|
2096
|
-
for (const b of m.content) {
|
|
2097
|
-
if (b.type === "text") total += this.estimator(b.text);
|
|
2098
|
-
else if (b.type === "tool_use") total += estimateToolInputTokens(b.input);
|
|
2099
|
-
else if (b.type === "tool_result") total += estimateToolResultTokens(b.content);
|
|
2100
|
-
}
|
|
2101
|
-
}
|
|
2102
|
-
}
|
|
2103
|
-
return total;
|
|
2201
|
+
ctx.state.replaceMessages([summaryMsg, ...tail]);
|
|
2202
|
+
return {
|
|
2203
|
+
saved: Math.max(0, removedTokens - estimateMessages([summaryMsg])),
|
|
2204
|
+
digest
|
|
2205
|
+
};
|
|
2104
2206
|
}
|
|
2105
2207
|
};
|
|
2106
2208
|
function readContextWindowPolicy(ctx) {
|
|
@@ -2112,10 +2214,6 @@ function readContextWindowPolicy(ctx) {
|
|
|
2112
2214
|
}
|
|
2113
2215
|
return candidate;
|
|
2114
2216
|
}
|
|
2115
|
-
function hasTextContent(m) {
|
|
2116
|
-
if (typeof m.content === "string") return m.content.trim().length > 0;
|
|
2117
|
-
return m.content.some((b) => b.type === "text" && b.text.trim().length > 0);
|
|
2118
|
-
}
|
|
2119
2217
|
var PROJECT_MARKERS = [
|
|
2120
2218
|
".git",
|
|
2121
2219
|
"package.json",
|
|
@@ -2322,6 +2420,7 @@ var DefaultRetryPolicy = class {
|
|
|
2322
2420
|
if (err instanceof ProviderError) {
|
|
2323
2421
|
if (err.status === 429) return 5;
|
|
2324
2422
|
if (err.status === 529) return 3;
|
|
2423
|
+
if (err.status === 599) return 5;
|
|
2325
2424
|
if (err.status >= 500) return 3;
|
|
2326
2425
|
return 0;
|
|
2327
2426
|
}
|
|
@@ -3362,6 +3461,8 @@ function topologicalSort(graph) {
|
|
|
3362
3461
|
var ToolCapabilities = {
|
|
3363
3462
|
/** Can execute arbitrary commands in the user's shell (the `bash` tool). */
|
|
3364
3463
|
SHELL_ARBITRARY: "shell.arbitrary",
|
|
3464
|
+
/** Can execute a restricted set of commands (the `exec` tool). */
|
|
3465
|
+
SHELL_RESTRICTED: "shell.restricted",
|
|
3365
3466
|
/** Can write / modify / delete files inside the project. */
|
|
3366
3467
|
FS_WRITE: "fs.write",
|
|
3367
3468
|
/** Can write files outside the current project root (very high risk). */
|
|
@@ -3377,6 +3478,7 @@ var ToolCapabilities = {
|
|
|
3377
3478
|
};
|
|
3378
3479
|
var DANGEROUS_FOR_SUBAGENTS = [
|
|
3379
3480
|
ToolCapabilities.SHELL_ARBITRARY,
|
|
3481
|
+
ToolCapabilities.SHELL_RESTRICTED,
|
|
3380
3482
|
ToolCapabilities.FS_WRITE,
|
|
3381
3483
|
ToolCapabilities.FS_WRITE_OUTSIDE_PROJECT,
|
|
3382
3484
|
ToolCapabilities.MCP_PROXY,
|
|
@@ -4451,7 +4553,7 @@ function computeTaskItemProgress(tasks) {
|
|
|
4451
4553
|
let failed = 0;
|
|
4452
4554
|
let review = 0;
|
|
4453
4555
|
let estimatedHours = 0;
|
|
4454
|
-
|
|
4556
|
+
const actualHours = 0;
|
|
4455
4557
|
for (const t2 of tasks) {
|
|
4456
4558
|
switch (t2.status) {
|
|
4457
4559
|
case "completed":
|
|
@@ -4815,6 +4917,7 @@ function resolveWstackPaths(opts) {
|
|
|
4815
4917
|
projectTrust: path6.join(projectDir, "trust.json"),
|
|
4816
4918
|
projectMeta: path6.join(projectDir, "meta.json"),
|
|
4817
4919
|
projectLocalConfig: path6.join(projectDir, "config.local.json"),
|
|
4920
|
+
inProjectConfig: path6.join(opts.projectRoot, ".wrongstack", "config.json"),
|
|
4818
4921
|
inProjectAgentsFile: path6.join(opts.projectRoot, ".wrongstack", "AGENTS.md"),
|
|
4819
4922
|
inProjectSkills: path6.join(opts.projectRoot, ".wrongstack", "skills"),
|
|
4820
4923
|
inProjectWorktrees: path6.join(opts.projectRoot, ".wrongstack", "worktrees"),
|
|
@@ -4923,6 +5026,13 @@ function buildChildEnv(optsOrSessionId) {
|
|
|
4923
5026
|
function sleep(ms) {
|
|
4924
5027
|
return new Promise((resolve12) => setTimeout(resolve12, ms));
|
|
4925
5028
|
}
|
|
5029
|
+
|
|
5030
|
+
// src/utils/assert-never.ts
|
|
5031
|
+
function assertNever(x, message) {
|
|
5032
|
+
throw new Error(
|
|
5033
|
+
message ?? `Unhandled case: ${JSON.stringify(x)}`
|
|
5034
|
+
);
|
|
5035
|
+
}
|
|
4926
5036
|
var GLOB_CHARS = /* @__PURE__ */ new Set(["*", "?", "["]);
|
|
4927
5037
|
var IS_WINDOWS = process.platform === "win32";
|
|
4928
5038
|
var SEP = IS_WINDOWS ? "\\" : "/";
|
|
@@ -4985,7 +5095,7 @@ async function expandGlob(pattern) {
|
|
|
4985
5095
|
const abs = isAbsolute(pattern);
|
|
4986
5096
|
const base = abs ? baseDir(pattern) : baseDir(pattern);
|
|
4987
5097
|
const relPat = base === "." ? pattern : pattern.slice(base.length + 1);
|
|
4988
|
-
async function
|
|
5098
|
+
async function walk3(dir, pat) {
|
|
4989
5099
|
let entries;
|
|
4990
5100
|
try {
|
|
4991
5101
|
entries = await fsp3.readdir(dir);
|
|
@@ -5006,12 +5116,12 @@ async function expandGlob(pattern) {
|
|
|
5006
5116
|
const before = pat.slice(0, firstGlob);
|
|
5007
5117
|
const rest = pat.slice(firstGlob);
|
|
5008
5118
|
if (before.endsWith("**")) {
|
|
5009
|
-
await
|
|
5119
|
+
await walk3(dir, rest);
|
|
5010
5120
|
for (const e of entries) {
|
|
5011
5121
|
const full = `${dir}${SEP}${e}`;
|
|
5012
5122
|
try {
|
|
5013
5123
|
const stat11 = await fsp3.stat(full);
|
|
5014
|
-
if (stat11.isDirectory()) await
|
|
5124
|
+
if (stat11.isDirectory()) await walk3(full, rest);
|
|
5015
5125
|
} catch {
|
|
5016
5126
|
}
|
|
5017
5127
|
}
|
|
@@ -5029,13 +5139,13 @@ async function expandGlob(pattern) {
|
|
|
5029
5139
|
const full = `${dir}${SEP}${seg}`;
|
|
5030
5140
|
try {
|
|
5031
5141
|
const stat11 = await fsp3.stat(full);
|
|
5032
|
-
if (stat11.isDirectory()) await
|
|
5142
|
+
if (stat11.isDirectory()) await walk3(full, rest);
|
|
5033
5143
|
} catch {
|
|
5034
5144
|
}
|
|
5035
5145
|
}
|
|
5036
5146
|
}
|
|
5037
5147
|
}
|
|
5038
|
-
await
|
|
5148
|
+
await walk3(base === "." ? "." : base, relPat);
|
|
5039
5149
|
return [...results];
|
|
5040
5150
|
}
|
|
5041
5151
|
|
|
@@ -5206,8 +5316,7 @@ var DefaultSessionStore = class _DefaultSessionStore {
|
|
|
5206
5316
|
onClose: (s) => this.appendToIndex(s)
|
|
5207
5317
|
});
|
|
5208
5318
|
} catch (err) {
|
|
5209
|
-
await handle.close().catch(() => {
|
|
5210
|
-
});
|
|
5319
|
+
await handle.close().catch((e) => console.warn(`[session-store] handle.close() failed: ${e}`));
|
|
5211
5320
|
throw err;
|
|
5212
5321
|
}
|
|
5213
5322
|
}
|
|
@@ -5238,8 +5347,7 @@ var DefaultSessionStore = class _DefaultSessionStore {
|
|
|
5238
5347
|
);
|
|
5239
5348
|
return { writer, data };
|
|
5240
5349
|
} catch (err) {
|
|
5241
|
-
await handle.close().catch(() => {
|
|
5242
|
-
});
|
|
5350
|
+
await handle.close().catch((e) => console.warn(`[session-store] handle.close() failed: ${e}`));
|
|
5243
5351
|
throw err;
|
|
5244
5352
|
}
|
|
5245
5353
|
}
|
|
@@ -5428,15 +5536,15 @@ var DefaultSessionStore = class _DefaultSessionStore {
|
|
|
5428
5536
|
* sidecars, and the session directory (fleet.json, shared/, subagents/).
|
|
5429
5537
|
*/
|
|
5430
5538
|
async deleteSession(id) {
|
|
5431
|
-
await fsp3.unlink(this.sessionPath(id, ".jsonl")).catch(() =>
|
|
5432
|
-
await fsp3.unlink(this.sessionPath(id, ".summary.json")).catch(() =>
|
|
5539
|
+
await fsp3.unlink(this.sessionPath(id, ".jsonl")).catch((err) => console.warn(`[session-store] delete .jsonl failed: ${err}`));
|
|
5540
|
+
await fsp3.unlink(this.sessionPath(id, ".summary.json")).catch((err) => console.warn(`[session-store] delete .summary.json failed: ${err}`));
|
|
5433
5541
|
const shardDir = path6.dirname(path6.join(this.dir, id));
|
|
5434
5542
|
const base = path6.basename(id);
|
|
5435
5543
|
for (const ext of [".plan.json", ".todos.json"]) {
|
|
5436
|
-
await fsp3.unlink(path6.join(shardDir, `${base}${ext}`)).catch(() =>
|
|
5544
|
+
await fsp3.unlink(path6.join(shardDir, `${base}${ext}`)).catch((err) => console.warn(`[session-store] delete ${ext} failed: ${err}`));
|
|
5437
5545
|
}
|
|
5438
5546
|
const sessDir = path6.join(shardDir, base);
|
|
5439
|
-
await fsp3.rm(sessDir, { recursive: true, force: true }).catch(() =>
|
|
5547
|
+
await fsp3.rm(sessDir, { recursive: true, force: true }).catch((err) => console.warn(`[session-store] delete session dir failed: ${err}`));
|
|
5440
5548
|
await this.writeTombstone(id);
|
|
5441
5549
|
}
|
|
5442
5550
|
async delete(id) {
|
|
@@ -6252,39 +6360,41 @@ ${line}`;
|
|
|
6252
6360
|
}
|
|
6253
6361
|
async forget(scope, query, filePath) {
|
|
6254
6362
|
const file = this.resolveFile(filePath, scope);
|
|
6255
|
-
|
|
6256
|
-
|
|
6257
|
-
|
|
6258
|
-
|
|
6259
|
-
|
|
6260
|
-
|
|
6261
|
-
|
|
6262
|
-
|
|
6263
|
-
|
|
6264
|
-
|
|
6265
|
-
const
|
|
6266
|
-
|
|
6267
|
-
|
|
6268
|
-
|
|
6269
|
-
|
|
6363
|
+
return withFileLock(file, async () => {
|
|
6364
|
+
let existing;
|
|
6365
|
+
try {
|
|
6366
|
+
existing = await fsp3.readFile(file, "utf8");
|
|
6367
|
+
} catch {
|
|
6368
|
+
return 0;
|
|
6369
|
+
}
|
|
6370
|
+
const needle = query.toLowerCase();
|
|
6371
|
+
const idMatcher = /mem_\d+_\w+/;
|
|
6372
|
+
let removed = 0;
|
|
6373
|
+
const lines = existing.split("\n").filter((line) => {
|
|
6374
|
+
const trimmed = line.trim();
|
|
6375
|
+
if (!trimmed.startsWith("- ")) return true;
|
|
6376
|
+
if (idMatcher.test(query)) {
|
|
6377
|
+
const entryIdMatch = /mem_\d+_\w+/.exec(trimmed);
|
|
6378
|
+
if (entryIdMatch && entryIdMatch[0] === query) {
|
|
6379
|
+
removed++;
|
|
6380
|
+
return false;
|
|
6381
|
+
}
|
|
6382
|
+
}
|
|
6383
|
+
if (trimmed.toLowerCase().includes(needle)) {
|
|
6270
6384
|
removed++;
|
|
6271
6385
|
return false;
|
|
6272
6386
|
}
|
|
6387
|
+
return true;
|
|
6388
|
+
});
|
|
6389
|
+
if (removed > 0) {
|
|
6390
|
+
if (lines.length === 0 || lines.length === 1 && !lines[0]?.trim()) {
|
|
6391
|
+
await atomicWrite(file, "");
|
|
6392
|
+
} else {
|
|
6393
|
+
await atomicWrite(file, lines.join("\n"));
|
|
6394
|
+
}
|
|
6273
6395
|
}
|
|
6274
|
-
|
|
6275
|
-
removed++;
|
|
6276
|
-
return false;
|
|
6277
|
-
}
|
|
6278
|
-
return true;
|
|
6396
|
+
return removed;
|
|
6279
6397
|
});
|
|
6280
|
-
if (removed > 0) {
|
|
6281
|
-
if (lines.length === 0 || lines.length === 1 && !lines[0]?.trim()) {
|
|
6282
|
-
await atomicWrite(file, "");
|
|
6283
|
-
} else {
|
|
6284
|
-
await atomicWrite(file, lines.join("\n"));
|
|
6285
|
-
}
|
|
6286
|
-
}
|
|
6287
|
-
return removed;
|
|
6288
6398
|
}
|
|
6289
6399
|
async readAll(scope, filePath) {
|
|
6290
6400
|
const file = this.resolveFile(filePath, scope);
|
|
@@ -6724,48 +6834,6 @@ function deepFreeze(obj) {
|
|
|
6724
6834
|
}
|
|
6725
6835
|
return Object.freeze(obj);
|
|
6726
6836
|
}
|
|
6727
|
-
|
|
6728
|
-
// src/security/config-secrets.ts
|
|
6729
|
-
function decryptConfigSecrets2(cfg, vault) {
|
|
6730
|
-
return walk3(cfg, vault, (v, key) => {
|
|
6731
|
-
try {
|
|
6732
|
-
return vault.decrypt(v);
|
|
6733
|
-
} catch (err) {
|
|
6734
|
-
console.warn(
|
|
6735
|
-
`[secret-vault] Failed to decrypt "${key}":`,
|
|
6736
|
-
err instanceof Error ? err.message : err
|
|
6737
|
-
);
|
|
6738
|
-
return "";
|
|
6739
|
-
}
|
|
6740
|
-
});
|
|
6741
|
-
}
|
|
6742
|
-
function walk3(node, vault, transform) {
|
|
6743
|
-
if (node === null || node === void 0) return node;
|
|
6744
|
-
if (typeof node !== "object") return node;
|
|
6745
|
-
if (Array.isArray(node)) {
|
|
6746
|
-
return node.map((item) => walk3(item, vault, transform));
|
|
6747
|
-
}
|
|
6748
|
-
const out = /* @__PURE__ */ Object.create(null);
|
|
6749
|
-
for (const [k, v] of Object.entries(node)) {
|
|
6750
|
-
if (typeof v === "string" && isSecretField2(k)) {
|
|
6751
|
-
out[k] = transform(v, k);
|
|
6752
|
-
} else if (typeof v === "object" && v !== null) {
|
|
6753
|
-
out[k] = walk3(v, vault, transform);
|
|
6754
|
-
} else {
|
|
6755
|
-
out[k] = v;
|
|
6756
|
-
}
|
|
6757
|
-
}
|
|
6758
|
-
return out;
|
|
6759
|
-
}
|
|
6760
|
-
var SECRET_KEY_PATTERN2 = /(?:apikey|api_key|authtoken|auth_token|bearer|secret|password|passwd|pwd|refreshtoken|refresh_token|sessionkey|session_key|access[_-]?token|private[_-]?key)/i;
|
|
6761
|
-
var NON_SECRET_OVERRIDES2 = /* @__PURE__ */ new Set(["publickey", "public_key"]);
|
|
6762
|
-
function isSecretField2(name) {
|
|
6763
|
-
const lc = name.toLowerCase();
|
|
6764
|
-
if (NON_SECRET_OVERRIDES2.has(lc)) return false;
|
|
6765
|
-
return SECRET_KEY_PATTERN2.test(lc);
|
|
6766
|
-
}
|
|
6767
|
-
|
|
6768
|
-
// src/storage/config-loader.ts
|
|
6769
6837
|
init_atomic_write();
|
|
6770
6838
|
var BEHAVIOR_DEFAULTS = {
|
|
6771
6839
|
version: 1,
|
|
@@ -6904,12 +6972,14 @@ var DefaultConfigLoader = class {
|
|
|
6904
6972
|
}
|
|
6905
6973
|
async load(opts = {}) {
|
|
6906
6974
|
let cfg = { ...BEHAVIOR_DEFAULTS };
|
|
6907
|
-
const [global, local] = await Promise.all([
|
|
6975
|
+
const [global, local, inProject] = await Promise.all([
|
|
6908
6976
|
this.readJson(this.paths.globalConfig),
|
|
6909
|
-
this.readJson(this.paths.projectLocalConfig)
|
|
6977
|
+
this.readJson(this.paths.projectLocalConfig),
|
|
6978
|
+
this.readJson(this.paths.inProjectConfig)
|
|
6910
6979
|
]);
|
|
6911
6980
|
cfg = deepMerge2(cfg, global);
|
|
6912
6981
|
cfg = deepMerge2(cfg, local);
|
|
6982
|
+
cfg = deepMerge2(cfg, inProject);
|
|
6913
6983
|
for (const [key, fn] of Object.entries(ENV_MAP)) {
|
|
6914
6984
|
const v = process.env[key];
|
|
6915
6985
|
if (v) fn(cfg, v);
|
|
@@ -6933,7 +7003,7 @@ var DefaultConfigLoader = class {
|
|
|
6933
7003
|
cfg = deepMerge2(cfg, opts.cliFlags);
|
|
6934
7004
|
}
|
|
6935
7005
|
if (this.vault) {
|
|
6936
|
-
cfg =
|
|
7006
|
+
cfg = decryptConfigSecrets(cfg, this.vault);
|
|
6937
7007
|
}
|
|
6938
7008
|
if (cfg.providers) {
|
|
6939
7009
|
for (const pcfg of Object.values(cfg.providers)) {
|
|
@@ -6983,7 +7053,7 @@ var DefaultConfigLoader = class {
|
|
|
6983
7053
|
const parsed = safeParse(raw);
|
|
6984
7054
|
if (!parsed.ok || !parsed.value) return null;
|
|
6985
7055
|
if (this.vault) {
|
|
6986
|
-
const decrypted =
|
|
7056
|
+
const decrypted = decryptConfigSecrets({ sync: parsed.value }, this.vault);
|
|
6987
7057
|
return decrypted.sync ?? null;
|
|
6988
7058
|
}
|
|
6989
7059
|
return parsed.value;
|
|
@@ -8266,38 +8336,15 @@ var DefaultPermissionPolicy = class {
|
|
|
8266
8336
|
}
|
|
8267
8337
|
};
|
|
8268
8338
|
var AutoApprovePermissionPolicy = class _AutoApprovePermissionPolicy {
|
|
8269
|
-
/**
|
|
8270
|
-
* Legacy name-based denylist.
|
|
8271
|
-
* @deprecated Prefer declaring `capabilities` on the Tool and using capability-based checks.
|
|
8272
|
-
*/
|
|
8273
|
-
static LEGACY_NAME_DENY = /* @__PURE__ */ new Set([
|
|
8274
|
-
"bash",
|
|
8275
|
-
"write",
|
|
8276
|
-
"edit",
|
|
8277
|
-
"replace",
|
|
8278
|
-
"scaffold",
|
|
8279
|
-
"patch",
|
|
8280
|
-
"install",
|
|
8281
|
-
"exec"
|
|
8282
|
-
]);
|
|
8283
|
-
// Note: hasDangerousCapabilityForSubagents is now the shared helper from capabilities.ts
|
|
8284
|
-
// The old private method was removed in favor of the centralized utility.
|
|
8285
|
-
/**
|
|
8286
|
-
* Tools from MCP servers (`mcp__<server>__<tool>`) are external code of
|
|
8287
|
-
* unknown capability — they may wrap a shell or filesystem. They are
|
|
8288
|
-
* fail-closed here: not auto-approved for subagents by default, so the
|
|
8289
|
-
* leader must allow them explicitly per-spawn.
|
|
8290
|
-
*/
|
|
8291
8339
|
static isMcpTool(name) {
|
|
8292
8340
|
return name.startsWith("mcp__");
|
|
8293
8341
|
}
|
|
8294
8342
|
async evaluate(tool) {
|
|
8295
8343
|
const hasDangerousCap = hasDangerousCapabilityForSubagents(tool);
|
|
8296
|
-
const legacyNameBlock = _AutoApprovePermissionPolicy.LEGACY_NAME_DENY.has(tool.name);
|
|
8297
8344
|
const isMcp = _AutoApprovePermissionPolicy.isMcpTool(tool.name);
|
|
8298
|
-
const blocked = tool.permission === "deny" || hasDangerousCap ||
|
|
8345
|
+
const blocked = tool.permission === "deny" || hasDangerousCap || isMcp;
|
|
8299
8346
|
if (blocked) {
|
|
8300
|
-
const reason = hasDangerousCap ? `tool declares dangerous capability (${tool.capabilities?.join(", ")}) \u2014 not auto-approved for subagents` :
|
|
8347
|
+
const reason = hasDangerousCap ? `tool declares dangerous capability (${tool.capabilities?.join(", ")}) \u2014 not auto-approved for subagents` : isMcp ? `MCP tool ${tool.name} is not auto-approved for subagents \u2014 ask the leader to allow it explicitly` : "tool default deny";
|
|
8301
8348
|
return {
|
|
8302
8349
|
permission: "deny",
|
|
8303
8350
|
source: "subagent_guard",
|
|
@@ -8599,53 +8646,63 @@ async function streamProviderToResponse(provider, req, signal, ctx, events) {
|
|
|
8599
8646
|
const next = await iter.next();
|
|
8600
8647
|
if (next.done) break;
|
|
8601
8648
|
const ev = next.value;
|
|
8602
|
-
|
|
8603
|
-
|
|
8604
|
-
|
|
8605
|
-
|
|
8606
|
-
|
|
8607
|
-
|
|
8608
|
-
|
|
8609
|
-
|
|
8610
|
-
|
|
8611
|
-
|
|
8612
|
-
|
|
8613
|
-
|
|
8614
|
-
|
|
8615
|
-
|
|
8616
|
-
|
|
8617
|
-
|
|
8618
|
-
|
|
8619
|
-
|
|
8620
|
-
|
|
8621
|
-
|
|
8622
|
-
|
|
8623
|
-
|
|
8624
|
-
|
|
8625
|
-
|
|
8626
|
-
|
|
8627
|
-
|
|
8628
|
-
|
|
8629
|
-
|
|
8630
|
-
|
|
8631
|
-
|
|
8649
|
+
try {
|
|
8650
|
+
switch (ev.type) {
|
|
8651
|
+
case "message_start":
|
|
8652
|
+
handleMessageStart(state, ev.model);
|
|
8653
|
+
break;
|
|
8654
|
+
case "content_block_start":
|
|
8655
|
+
handleContentBlockStart(state, ev);
|
|
8656
|
+
break;
|
|
8657
|
+
case "content_block_stop":
|
|
8658
|
+
handleContentBlockStop(state, ev);
|
|
8659
|
+
break;
|
|
8660
|
+
case "text_delta":
|
|
8661
|
+
handleTextDelta(state, ev.text);
|
|
8662
|
+
events.emit("provider.text_delta", { ctx, text: ev.text });
|
|
8663
|
+
break;
|
|
8664
|
+
case "tool_use_start": {
|
|
8665
|
+
const idVal = ev.id;
|
|
8666
|
+
const nameVal = ev.name;
|
|
8667
|
+
handleToolUseStart(state, { id: idVal, name: nameVal });
|
|
8668
|
+
const emittedPayload = { ctx, id: idVal ?? "unknown", name: nameVal ?? "unknown" };
|
|
8669
|
+
events.emit("provider.tool_use_start", emittedPayload);
|
|
8670
|
+
break;
|
|
8671
|
+
}
|
|
8672
|
+
case "tool_use_input_delta":
|
|
8673
|
+
handleToolUseInputDelta(state, ev);
|
|
8674
|
+
break;
|
|
8675
|
+
case "tool_use_stop": {
|
|
8676
|
+
const stoppedName = state.tools.get(ev.id)?.name ?? "unknown";
|
|
8677
|
+
handleToolUseStop(state, ev);
|
|
8678
|
+
events.emit("provider.tool_use_stop", { ctx, id: ev.id, name: stoppedName });
|
|
8679
|
+
break;
|
|
8680
|
+
}
|
|
8681
|
+
case "thinking_start":
|
|
8682
|
+
handleThinkingStart(state, ev);
|
|
8683
|
+
break;
|
|
8684
|
+
case "thinking_delta":
|
|
8685
|
+
handleThinkingDelta(state, ev.text);
|
|
8686
|
+
events.emit("provider.thinking_delta", { ctx, text: ev.text });
|
|
8687
|
+
break;
|
|
8688
|
+
case "thinking_signature":
|
|
8689
|
+
handleThinkingSignature(state, ev.signature);
|
|
8690
|
+
break;
|
|
8691
|
+
case "thinking_stop":
|
|
8692
|
+
handleThinkingStop(state);
|
|
8693
|
+
break;
|
|
8694
|
+
case "message_stop":
|
|
8695
|
+
handleMessageStop(state, ev);
|
|
8696
|
+
break;
|
|
8697
|
+
default:
|
|
8698
|
+
break;
|
|
8632
8699
|
}
|
|
8633
|
-
|
|
8634
|
-
|
|
8635
|
-
|
|
8636
|
-
|
|
8637
|
-
|
|
8638
|
-
|
|
8639
|
-
break;
|
|
8640
|
-
case "thinking_signature":
|
|
8641
|
-
handleThinkingSignature(state, ev.signature);
|
|
8642
|
-
break;
|
|
8643
|
-
case "thinking_stop":
|
|
8644
|
-
handleThinkingStop(state);
|
|
8645
|
-
break;
|
|
8646
|
-
case "message_stop":
|
|
8647
|
-
handleMessageStop(state, ev);
|
|
8648
|
-
break;
|
|
8700
|
+
} catch (handlerErr) {
|
|
8701
|
+
events.emit("provider.stream_error", {
|
|
8702
|
+
ctx,
|
|
8703
|
+
eventType: ev.type,
|
|
8704
|
+
msg: handlerErr instanceof Error ? handlerErr.message : String(handlerErr)
|
|
8705
|
+
});
|
|
8649
8706
|
}
|
|
8650
8707
|
}
|
|
8651
8708
|
} catch (err) {
|
|
@@ -8658,8 +8715,10 @@ async function streamProviderToResponse(provider, req, signal, ctx, events) {
|
|
|
8658
8715
|
try {
|
|
8659
8716
|
let drainTimer = null;
|
|
8660
8717
|
try {
|
|
8718
|
+
const drainPromise = Promise.resolve(iter.return?.()).catch(() => {
|
|
8719
|
+
});
|
|
8661
8720
|
await Promise.race([
|
|
8662
|
-
|
|
8721
|
+
drainPromise,
|
|
8663
8722
|
new Promise((resolve12) => {
|
|
8664
8723
|
drainTimer = setTimeout(resolve12, STREAM_DRAIN_TIMEOUT_MS);
|
|
8665
8724
|
})
|
|
@@ -8778,23 +8837,25 @@ var IntelligentCompactor = class {
|
|
|
8778
8837
|
this.summarizerModel = opts.summarizerModel;
|
|
8779
8838
|
}
|
|
8780
8839
|
async compact(ctx, opts = {}) {
|
|
8781
|
-
const beforeTokens =
|
|
8840
|
+
const beforeTokens = estimateMessages(ctx.messages);
|
|
8782
8841
|
const beforeFull = this.estimateFullRequest(ctx);
|
|
8783
8842
|
const reductions = [];
|
|
8784
8843
|
const load = beforeFull / this.maxContext;
|
|
8785
8844
|
const aggressive = load >= this.hardThreshold ? true : opts.aggressive ?? load >= this.softThreshold;
|
|
8786
|
-
const saved1 = this.
|
|
8845
|
+
const saved1 = this.elide(ctx);
|
|
8787
8846
|
if (saved1 > 0) reductions.push({ phase: "elision", saved: saved1 });
|
|
8847
|
+
let collapsedDigest;
|
|
8788
8848
|
if (aggressive) {
|
|
8789
|
-
const
|
|
8790
|
-
if (
|
|
8849
|
+
const phase2 = await this.summarizeAncientTurns(ctx);
|
|
8850
|
+
if (phase2.saved > 0) reductions.push({ phase: "summary", saved: phase2.saved });
|
|
8851
|
+
collapsedDigest = phase2.digest;
|
|
8791
8852
|
} else if (load >= this.warnThreshold) {
|
|
8792
|
-
const saved2 = this.
|
|
8853
|
+
const saved2 = this.elide(ctx);
|
|
8793
8854
|
if (saved2 > 0) reductions.push({ phase: "elision", saved: saved2 });
|
|
8794
8855
|
}
|
|
8795
8856
|
const repaired = repairToolUseAdjacency(ctx.messages);
|
|
8796
8857
|
if (repaired.report.changed) ctx.state.replaceMessages(repaired.messages);
|
|
8797
|
-
const afterTokens =
|
|
8858
|
+
const afterTokens = estimateMessages(ctx.messages);
|
|
8798
8859
|
const afterFull = this.estimateFullRequest(ctx);
|
|
8799
8860
|
return {
|
|
8800
8861
|
before: beforeTokens,
|
|
@@ -8802,6 +8863,7 @@ var IntelligentCompactor = class {
|
|
|
8802
8863
|
fullRequestTokensBefore: beforeFull,
|
|
8803
8864
|
fullRequestTokensAfter: afterFull,
|
|
8804
8865
|
reductions,
|
|
8866
|
+
collapsedDigest,
|
|
8805
8867
|
repaired: repaired.report.changed ? {
|
|
8806
8868
|
removedToolUses: repaired.report.removedToolUses,
|
|
8807
8869
|
removedToolResults: repaired.report.removedToolResults,
|
|
@@ -8814,75 +8876,39 @@ var IntelligentCompactor = class {
|
|
|
8814
8876
|
* This is the accurate figure for context-window pressure monitoring.
|
|
8815
8877
|
*/
|
|
8816
8878
|
estimateFullRequest(ctx) {
|
|
8817
|
-
|
|
8818
|
-
|
|
8879
|
+
return estimateRequestTokens(ctx.messages, ctx.systemPrompt, ctx.tools ?? []).total;
|
|
8880
|
+
}
|
|
8881
|
+
/** Run shared tool-result elision and commit through ConversationState. */
|
|
8882
|
+
elide(ctx) {
|
|
8883
|
+
const result = eliseOldToolResults(ctx.messages, {
|
|
8884
|
+
preserveK: this.preserveK,
|
|
8885
|
+
eliseThreshold: this.eliseThreshold
|
|
8886
|
+
});
|
|
8887
|
+
if (result.changed) ctx.state.replaceMessages(result.messages);
|
|
8888
|
+
return result.saved;
|
|
8819
8889
|
}
|
|
8820
8890
|
async summarizeAncientTurns(ctx) {
|
|
8821
8891
|
const messages = ctx.messages;
|
|
8822
8892
|
const cutoff = Math.max(0, messages.length - this.preserveK * 2);
|
|
8823
|
-
if (cutoff <= 2) return 0;
|
|
8824
|
-
const boundary =
|
|
8825
|
-
if (boundary <= 1) return 0;
|
|
8893
|
+
if (cutoff <= 2) return { saved: 0 };
|
|
8894
|
+
const boundary = findSafeBoundary(messages, 0, cutoff);
|
|
8895
|
+
if (boundary <= 1) return { saved: 0 };
|
|
8826
8896
|
const toSummarize = messages.slice(0, boundary);
|
|
8827
|
-
const removedTokens =
|
|
8897
|
+
const removedTokens = estimateMessages(toSummarize);
|
|
8828
8898
|
let summaryText;
|
|
8829
8899
|
try {
|
|
8830
8900
|
summaryText = await this.callSummarizer(toSummarize, ctx);
|
|
8831
8901
|
} catch {
|
|
8832
|
-
|
|
8833
|
-
for (const m of toSummarize) {
|
|
8834
|
-
if (m.role === "system") continue;
|
|
8835
|
-
if (typeof m.content === "string") {
|
|
8836
|
-
preservedMessages.push(m);
|
|
8837
|
-
} else if (Array.isArray(m.content)) {
|
|
8838
|
-
const textParts = m.content.filter(isTextBlock);
|
|
8839
|
-
const toolParts = m.content.filter((b) => b.type === "tool_use" || b.type === "tool_result");
|
|
8840
|
-
const next = {
|
|
8841
|
-
role: m.role,
|
|
8842
|
-
content: [
|
|
8843
|
-
...textParts,
|
|
8844
|
-
...toolParts.length > 0 ? [{ type: "text", text: `[${toolParts.length} tool call(s) omitted]` }] : []
|
|
8845
|
-
]
|
|
8846
|
-
};
|
|
8847
|
-
preservedMessages.push(next);
|
|
8848
|
-
}
|
|
8849
|
-
}
|
|
8850
|
-
summaryText = preservedMessages.map((m) => `[${m.role}]: ${typeof m.content === "string" ? m.content : m.content.filter(isTextBlock).map((b) => b.text).join(" ")}`).join("\n");
|
|
8851
|
-
if (!summaryText) summaryText = `${toSummarize.length} earlier turns (semantic content preserved)`;
|
|
8902
|
+
summaryText = buildLosslessDigest(toSummarize) || `${toSummarize.length} earlier turns (semantic content preserved)`;
|
|
8852
8903
|
}
|
|
8853
8904
|
const summaryMsg = {
|
|
8854
8905
|
role: "system",
|
|
8855
8906
|
content: `[prior_turns_summary: ${summaryText}]`
|
|
8856
8907
|
};
|
|
8857
|
-
const summaryTokens =
|
|
8908
|
+
const summaryTokens = estimateMessages([summaryMsg]);
|
|
8858
8909
|
const tail = ctx.messages.slice(boundary);
|
|
8859
8910
|
ctx.state.replaceMessages([summaryMsg, ...tail]);
|
|
8860
|
-
return Math.max(0, removedTokens - summaryTokens);
|
|
8861
|
-
}
|
|
8862
|
-
findSafeBoundary(messages, from, to) {
|
|
8863
|
-
for (let i = to; i >= from; i--) {
|
|
8864
|
-
const m = messages[i];
|
|
8865
|
-
if (!m) continue;
|
|
8866
|
-
if (m.role === "user" && this.hasTextContent(m)) {
|
|
8867
|
-
return this.findExchangeStart(messages, i);
|
|
8868
|
-
}
|
|
8869
|
-
}
|
|
8870
|
-
return -1;
|
|
8871
|
-
}
|
|
8872
|
-
findExchangeStart(messages, userIndex) {
|
|
8873
|
-
for (let i = userIndex - 1; i >= 0; i--) {
|
|
8874
|
-
const m = messages[i];
|
|
8875
|
-
if (!m) continue;
|
|
8876
|
-
if (m.role === "assistant") {
|
|
8877
|
-
const hasToolUse2 = Array.isArray(m.content) ? m.content.some((b) => b.type === "tool_use") : false;
|
|
8878
|
-
if (!hasToolUse2) {
|
|
8879
|
-
return i + 1;
|
|
8880
|
-
}
|
|
8881
|
-
} else if (m.role !== "user") ; else {
|
|
8882
|
-
return i;
|
|
8883
|
-
}
|
|
8884
|
-
}
|
|
8885
|
-
return 0;
|
|
8911
|
+
return { saved: Math.max(0, removedTokens - summaryTokens), digest: summaryText };
|
|
8886
8912
|
}
|
|
8887
8913
|
async callSummarizer(messages, ctx) {
|
|
8888
8914
|
const prompt = [
|
|
@@ -8917,86 +8943,6 @@ var IntelligentCompactor = class {
|
|
|
8917
8943
|
}
|
|
8918
8944
|
return [{ type: "text", text: lines.join("\n") }];
|
|
8919
8945
|
}
|
|
8920
|
-
lightweightCompact(ctx) {
|
|
8921
|
-
return this.eliseOldToolResults(ctx);
|
|
8922
|
-
}
|
|
8923
|
-
eliseOldToolResults(ctx) {
|
|
8924
|
-
const messages = ctx.messages;
|
|
8925
|
-
let pairCount = 0;
|
|
8926
|
-
let preserveStart = messages.length;
|
|
8927
|
-
for (let i = messages.length - 1; i >= 0 && pairCount < this.preserveK; i--) {
|
|
8928
|
-
const m = messages[i];
|
|
8929
|
-
if (!m) continue;
|
|
8930
|
-
if (m.role === "user" || m.role === "assistant") {
|
|
8931
|
-
pairCount++;
|
|
8932
|
-
preserveStart = i;
|
|
8933
|
-
}
|
|
8934
|
-
}
|
|
8935
|
-
for (let i = preserveStart; i < messages.length; i++) {
|
|
8936
|
-
const m = messages[i];
|
|
8937
|
-
if (!m || typeof m.content === "string" || !Array.isArray(m.content)) continue;
|
|
8938
|
-
const hasToolUse2 = m.content.some((b) => b.type === "tool_use");
|
|
8939
|
-
if (hasToolUse2 && i + 1 < messages.length) {
|
|
8940
|
-
const next = messages[i + 1];
|
|
8941
|
-
if (next && next.role === "user" && typeof next.content !== "string" && Array.isArray(next.content) && next.content.some((b) => b.type === "tool_result")) {
|
|
8942
|
-
preserveStart = i + 1;
|
|
8943
|
-
}
|
|
8944
|
-
}
|
|
8945
|
-
}
|
|
8946
|
-
let saved = 0;
|
|
8947
|
-
let changed = false;
|
|
8948
|
-
const nextMessages = new Array(messages.length);
|
|
8949
|
-
for (let i = 0; i < messages.length; i++) {
|
|
8950
|
-
const msg = messages[i];
|
|
8951
|
-
if (i >= preserveStart) {
|
|
8952
|
-
nextMessages[i] = msg;
|
|
8953
|
-
continue;
|
|
8954
|
-
}
|
|
8955
|
-
if (!msg || !Array.isArray(msg.content)) {
|
|
8956
|
-
nextMessages[i] = msg;
|
|
8957
|
-
continue;
|
|
8958
|
-
}
|
|
8959
|
-
const newContent = msg.content.map((b) => {
|
|
8960
|
-
if (b.type !== "tool_result") return b;
|
|
8961
|
-
const tokens = estimateToolResultTokens(b.content);
|
|
8962
|
-
if (tokens < this.eliseThreshold) return b;
|
|
8963
|
-
saved += tokens;
|
|
8964
|
-
return {
|
|
8965
|
-
type: "tool_result",
|
|
8966
|
-
tool_use_id: b.tool_use_id,
|
|
8967
|
-
content: `[elided: ~${tokens} tokens]`,
|
|
8968
|
-
is_error: b.is_error
|
|
8969
|
-
};
|
|
8970
|
-
});
|
|
8971
|
-
if (newContent.length === msg.content.length && newContent.every((b, idx) => b === msg.content[idx])) {
|
|
8972
|
-
nextMessages[i] = msg;
|
|
8973
|
-
} else {
|
|
8974
|
-
nextMessages[i] = { ...msg, content: newContent };
|
|
8975
|
-
changed = true;
|
|
8976
|
-
}
|
|
8977
|
-
}
|
|
8978
|
-
if (changed) ctx.state.replaceMessages(nextMessages);
|
|
8979
|
-
return saved;
|
|
8980
|
-
}
|
|
8981
|
-
hasTextContent(m) {
|
|
8982
|
-
if (typeof m.content === "string") return m.content.trim().length > 0;
|
|
8983
|
-
return m.content.some((b) => b.type === "text" && b.text.trim().length > 0);
|
|
8984
|
-
}
|
|
8985
|
-
estimateTokens(messages) {
|
|
8986
|
-
let total = 0;
|
|
8987
|
-
for (const m of messages) {
|
|
8988
|
-
if (typeof m.content === "string") {
|
|
8989
|
-
total += estimateTextTokens(m.content);
|
|
8990
|
-
} else {
|
|
8991
|
-
for (const b of m.content) {
|
|
8992
|
-
if (b.type === "text") total += estimateTextTokens(b.text);
|
|
8993
|
-
else if (b.type === "tool_use") total += estimateToolInputTokens(b.input);
|
|
8994
|
-
else if (b.type === "tool_result") total += estimateToolResultTokens(b.content);
|
|
8995
|
-
}
|
|
8996
|
-
}
|
|
8997
|
-
}
|
|
8998
|
-
return total;
|
|
8999
|
-
}
|
|
9000
8946
|
};
|
|
9001
8947
|
|
|
9002
8948
|
// src/models/llm-selector.ts
|
|
@@ -9022,20 +8968,6 @@ Rules:
|
|
|
9022
8968
|
- If unsure, keep rather than collapse (errors are more costly than waste)
|
|
9023
8969
|
|
|
9024
8970
|
Return ONLY the JSON object, no markdown, no explanation outside the JSON.`;
|
|
9025
|
-
function estimateTokens(messages) {
|
|
9026
|
-
let total = 0;
|
|
9027
|
-
for (const m of messages) {
|
|
9028
|
-
if (typeof m.content === "string") {
|
|
9029
|
-
total += Math.ceil(m.content.length / 4);
|
|
9030
|
-
} else if (Array.isArray(m.content)) {
|
|
9031
|
-
for (const b of m.content) {
|
|
9032
|
-
if (b.type === "text") total += Math.ceil(b.text.length / 4);
|
|
9033
|
-
else total += Math.ceil(JSON.stringify(b).length / 4);
|
|
9034
|
-
}
|
|
9035
|
-
}
|
|
9036
|
-
}
|
|
9037
|
-
return total;
|
|
9038
|
-
}
|
|
9039
8971
|
function formatMessages(messages, maxChars = 8e3) {
|
|
9040
8972
|
const lines = [];
|
|
9041
8973
|
let used = 0;
|
|
@@ -9074,7 +9006,7 @@ var LLMSelector = class {
|
|
|
9074
9006
|
async select(messages, maxToKeep) {
|
|
9075
9007
|
const effectiveBudget = Math.min(maxToKeep, this.maxContextTokens);
|
|
9076
9008
|
const historyText = formatMessages(messages);
|
|
9077
|
-
const totalTokens =
|
|
9009
|
+
const totalTokens = estimateMessageTokens(messages);
|
|
9078
9010
|
const systemText = `${this.systemPrompt}
|
|
9079
9011
|
|
|
9080
9012
|
Conversation (${messages.length} messages, ~${totalTokens} tokens, budget: ${effectiveBudget}):
|
|
@@ -9106,10 +9038,7 @@ IMPORTANT: Total conversation (${totalTokens} tokens) exceeds budget (${effectiv
|
|
|
9106
9038
|
let startIdx = 0;
|
|
9107
9039
|
for (let i = messages.length - 1; i >= 0; i--) {
|
|
9108
9040
|
const m = expectDefined(messages[i]);
|
|
9109
|
-
const cost =
|
|
9110
|
-
(acc, b) => acc + (b.type === "text" ? Math.ceil(b.text.length / 4) : Math.ceil(JSON.stringify(b).length / 4)),
|
|
9111
|
-
0
|
|
9112
|
-
);
|
|
9041
|
+
const cost = estimateMessageTokens([m]);
|
|
9113
9042
|
if (tokenCount + cost <= budget) {
|
|
9114
9043
|
tokenCount += cost;
|
|
9115
9044
|
} else {
|
|
@@ -9342,52 +9271,12 @@ Summarize the following message range:`;
|
|
|
9342
9271
|
return Math.floor(this.maxContext * 0.75);
|
|
9343
9272
|
}
|
|
9344
9273
|
eliseOldToolResults(ctx) {
|
|
9345
|
-
const
|
|
9346
|
-
|
|
9347
|
-
|
|
9348
|
-
|
|
9349
|
-
|
|
9350
|
-
|
|
9351
|
-
if (m.role === "user" || m.role === "assistant") {
|
|
9352
|
-
pairCount++;
|
|
9353
|
-
preserveStart = i;
|
|
9354
|
-
}
|
|
9355
|
-
}
|
|
9356
|
-
let saved = 0;
|
|
9357
|
-
let changed = false;
|
|
9358
|
-
const nextMessages = new Array(messages.length);
|
|
9359
|
-
for (let i = 0; i < messages.length; i++) {
|
|
9360
|
-
const msg = messages[i];
|
|
9361
|
-
if (i >= preserveStart) {
|
|
9362
|
-
nextMessages[i] = msg;
|
|
9363
|
-
continue;
|
|
9364
|
-
}
|
|
9365
|
-
if (!msg || !Array.isArray(msg.content)) {
|
|
9366
|
-
nextMessages[i] = msg;
|
|
9367
|
-
continue;
|
|
9368
|
-
}
|
|
9369
|
-
const newContent = msg.content.map((b) => {
|
|
9370
|
-
if (b.type !== "tool_result") return b;
|
|
9371
|
-
const text = typeof b.content === "string" ? b.content : JSON.stringify(b.content);
|
|
9372
|
-
const tokens = this.roughTokenEstimate(text);
|
|
9373
|
-
if (tokens < this.eliseThreshold) return b;
|
|
9374
|
-
saved += tokens;
|
|
9375
|
-
return {
|
|
9376
|
-
type: "tool_result",
|
|
9377
|
-
tool_use_id: b.tool_use_id,
|
|
9378
|
-
content: `[elided: ~${tokens} tokens]`,
|
|
9379
|
-
is_error: b.is_error
|
|
9380
|
-
};
|
|
9381
|
-
});
|
|
9382
|
-
if (newContent.every((b, idx) => b === msg.content[idx])) {
|
|
9383
|
-
nextMessages[i] = msg;
|
|
9384
|
-
} else {
|
|
9385
|
-
nextMessages[i] = { ...msg, content: newContent };
|
|
9386
|
-
changed = true;
|
|
9387
|
-
}
|
|
9388
|
-
}
|
|
9389
|
-
if (changed) ctx.state.replaceMessages(nextMessages);
|
|
9390
|
-
return saved;
|
|
9274
|
+
const result = eliseOldToolResults(ctx.messages, {
|
|
9275
|
+
preserveK: this.preserveK,
|
|
9276
|
+
eliseThreshold: this.eliseThreshold
|
|
9277
|
+
});
|
|
9278
|
+
if (result.changed) ctx.state.replaceMessages(result.messages);
|
|
9279
|
+
return result.saved;
|
|
9391
9280
|
}
|
|
9392
9281
|
hasTextContent(m) {
|
|
9393
9282
|
if (typeof m.content === "string") return m.content.trim().length > 0;
|
|
@@ -9417,8 +9306,80 @@ Summarize the following message range:`;
|
|
|
9417
9306
|
}
|
|
9418
9307
|
};
|
|
9419
9308
|
|
|
9309
|
+
// src/execution/strategy-compactor.ts
|
|
9310
|
+
function createStrategyCompactor(opts = {}) {
|
|
9311
|
+
const requested = opts.strategy ?? (opts.llmSelector ? "selective" : "hybrid");
|
|
9312
|
+
const strategy = requested;
|
|
9313
|
+
if (strategy === "intelligent" || strategy === "selective") {
|
|
9314
|
+
return new ProviderBackedCompactor(strategy, opts);
|
|
9315
|
+
}
|
|
9316
|
+
return new HybridCompactor({
|
|
9317
|
+
preserveK: opts.preserveK,
|
|
9318
|
+
eliseThreshold: opts.eliseThreshold
|
|
9319
|
+
});
|
|
9320
|
+
}
|
|
9321
|
+
var ProviderBackedCompactor = class {
|
|
9322
|
+
constructor(strategy, opts) {
|
|
9323
|
+
this.strategy = strategy;
|
|
9324
|
+
this.opts = opts;
|
|
9325
|
+
}
|
|
9326
|
+
strategy;
|
|
9327
|
+
opts;
|
|
9328
|
+
async compact(ctx, compactOpts = {}) {
|
|
9329
|
+
return this.resolveInner(ctx).compact(ctx, compactOpts);
|
|
9330
|
+
}
|
|
9331
|
+
/**
|
|
9332
|
+
* Construct the concrete compactor for this run. Rebuilt per call (cheap, no
|
|
9333
|
+
* I/O) so a model switch — which changes `ctx.provider.capabilities.maxContext`
|
|
9334
|
+
* — is always reflected. Reads the active ContextWindowPolicy from `ctx.meta`
|
|
9335
|
+
* so the LLM compactors honor the same thresholds/preserveK as the policy.
|
|
9336
|
+
*/
|
|
9337
|
+
resolveInner(ctx) {
|
|
9338
|
+
const provider = ctx.provider;
|
|
9339
|
+
if (!provider) {
|
|
9340
|
+
return new HybridCompactor({
|
|
9341
|
+
preserveK: this.opts.preserveK,
|
|
9342
|
+
eliseThreshold: this.opts.eliseThreshold
|
|
9343
|
+
});
|
|
9344
|
+
}
|
|
9345
|
+
const policy = readPolicy(ctx);
|
|
9346
|
+
const maxContext = provider.capabilities?.maxContext || void 0;
|
|
9347
|
+
const thresholds = policy?.thresholds;
|
|
9348
|
+
const common = {
|
|
9349
|
+
provider,
|
|
9350
|
+
maxContext,
|
|
9351
|
+
preserveK: this.opts.preserveK ?? policy?.preserveK,
|
|
9352
|
+
eliseThreshold: this.opts.eliseThreshold ?? policy?.eliseThreshold,
|
|
9353
|
+
...thresholds ? { warnThreshold: thresholds.warn, softThreshold: thresholds.soft, hardThreshold: thresholds.hard } : {}
|
|
9354
|
+
};
|
|
9355
|
+
if (this.strategy === "selective") {
|
|
9356
|
+
return new SelectiveCompactor({
|
|
9357
|
+
...common,
|
|
9358
|
+
selectorModel: this.opts.summarizerModel,
|
|
9359
|
+
summarizerModel: this.opts.summarizerModel
|
|
9360
|
+
});
|
|
9361
|
+
}
|
|
9362
|
+
return new IntelligentCompactor({
|
|
9363
|
+
...common,
|
|
9364
|
+
summarizerModel: this.opts.summarizerModel
|
|
9365
|
+
});
|
|
9366
|
+
}
|
|
9367
|
+
};
|
|
9368
|
+
function readPolicy(ctx) {
|
|
9369
|
+
const policy = ctx.meta?.["contextWindowPolicy"];
|
|
9370
|
+
if (!policy || typeof policy !== "object") return null;
|
|
9371
|
+
const candidate = policy;
|
|
9372
|
+
if (typeof candidate.preserveK !== "number" || !candidate.thresholds) return null;
|
|
9373
|
+
return candidate;
|
|
9374
|
+
}
|
|
9375
|
+
|
|
9420
9376
|
// src/execution/auto-compaction-middleware.ts
|
|
9421
9377
|
var LEVEL_RANK2 = { warn: 0, soft: 1, hard: 2 };
|
|
9378
|
+
var MAX_DIGEST_LOG_CHARS = 4e3;
|
|
9379
|
+
function truncateDigest(digest) {
|
|
9380
|
+
if (digest.length <= MAX_DIGEST_LOG_CHARS) return digest;
|
|
9381
|
+
return `${digest.slice(0, MAX_DIGEST_LOG_CHARS)}\u2026 [+${digest.length - MAX_DIGEST_LOG_CHARS} chars; full turns in session log]`;
|
|
9382
|
+
}
|
|
9422
9383
|
var AutoCompactionMiddleware = class _AutoCompactionMiddleware {
|
|
9423
9384
|
name = "AutoCompaction";
|
|
9424
9385
|
compactor;
|
|
@@ -9479,7 +9440,12 @@ var AutoCompactionMiddleware = class _AutoCompactionMiddleware {
|
|
|
9479
9440
|
}
|
|
9480
9441
|
handler() {
|
|
9481
9442
|
return async (ctx, next) => {
|
|
9482
|
-
const tokens = this._estimator ? this._estimator(ctx) : estimateRequestTokensCalibrated(
|
|
9443
|
+
const tokens = this._estimator ? this._estimator(ctx) : estimateRequestTokensCalibrated(
|
|
9444
|
+
ctx.messages,
|
|
9445
|
+
ctx.systemPrompt,
|
|
9446
|
+
ctx.tools ?? [],
|
|
9447
|
+
`${ctx.provider?.id ?? "unknown"}/${ctx.model}`
|
|
9448
|
+
).total;
|
|
9483
9449
|
const load = tokens / this._maxContext;
|
|
9484
9450
|
const policy = this.policyProvider?.(ctx);
|
|
9485
9451
|
const thresholds = policy?.thresholds ?? {
|
|
@@ -9541,7 +9507,11 @@ var AutoCompactionMiddleware = class _AutoCompactionMiddleware {
|
|
|
9541
9507
|
after: report.after,
|
|
9542
9508
|
level: pressure.level,
|
|
9543
9509
|
aggressive,
|
|
9544
|
-
reductions: report.reductions?.map((r) => ({ phase: r.phase, saved: r.saved }))
|
|
9510
|
+
reductions: report.reductions?.map((r) => ({ phase: r.phase, saved: r.saved })),
|
|
9511
|
+
// Record what was collapsed so the audit trail shows the preserved
|
|
9512
|
+
// content, not just token counts. Bounded to keep the log line small;
|
|
9513
|
+
// the full original turns are already in the session JSONL.
|
|
9514
|
+
...report.collapsedDigest ? { digest: truncateDigest(report.collapsedDigest) } : {}
|
|
9545
9515
|
});
|
|
9546
9516
|
ctx.clearFileTracking();
|
|
9547
9517
|
} catch (err) {
|
|
@@ -9626,6 +9596,12 @@ var DoneConditionChecker = class {
|
|
|
9626
9596
|
return { done: true, reason: `max tool calls (${this.condition.maxToolCalls}) reached`, ...state };
|
|
9627
9597
|
}
|
|
9628
9598
|
break;
|
|
9599
|
+
case "all_tasks_done":
|
|
9600
|
+
break;
|
|
9601
|
+
case "custom":
|
|
9602
|
+
break;
|
|
9603
|
+
default:
|
|
9604
|
+
return assertNever(this.condition.type);
|
|
9629
9605
|
}
|
|
9630
9606
|
return { done: false, iterations: state.iterations, toolCalls: state.toolCalls };
|
|
9631
9607
|
}
|
|
@@ -9748,16 +9724,20 @@ async function loadGoal(filePath) {
|
|
|
9748
9724
|
let raw;
|
|
9749
9725
|
try {
|
|
9750
9726
|
raw = await fsp3.readFile(filePath, "utf8");
|
|
9751
|
-
} catch {
|
|
9752
|
-
|
|
9727
|
+
} catch (err) {
|
|
9728
|
+
const code = err.code;
|
|
9729
|
+
if (code === "ENOENT") return null;
|
|
9730
|
+
throw err;
|
|
9753
9731
|
}
|
|
9754
9732
|
try {
|
|
9755
9733
|
const parsed = JSON.parse(raw);
|
|
9756
9734
|
if (parsed?.version !== 1 || typeof parsed.goal !== "string" || !Array.isArray(parsed.journal)) {
|
|
9735
|
+
console.warn(`[goal-store] Corrupt goal.json at ${filePath} \u2014 invalid schema. Consider deleting it and re-creating.`);
|
|
9757
9736
|
return null;
|
|
9758
9737
|
}
|
|
9759
9738
|
return parsed;
|
|
9760
9739
|
} catch {
|
|
9740
|
+
console.warn(`[goal-store] Corrupt goal.json at ${filePath} \u2014 JSON parse failed. Consider deleting it and re-creating.`);
|
|
9761
9741
|
return null;
|
|
9762
9742
|
}
|
|
9763
9743
|
}
|
|
@@ -9884,9 +9864,9 @@ function parseProgressFromText(text) {
|
|
|
9884
9864
|
const re = /\[progress:\s*(\d{1,3})%\]\s*(?:[—\-]\s*(.+))?/i;
|
|
9885
9865
|
const m = text.match(re);
|
|
9886
9866
|
if (!m) return null;
|
|
9887
|
-
const progress = Math.min(100, Math.max(0, Number.parseInt(m[1], 10)));
|
|
9867
|
+
const progress = Math.min(100, Math.max(0, Number.parseInt(m[1] ?? "0", 10)));
|
|
9888
9868
|
const note = m[2]?.trim() || void 0;
|
|
9889
|
-
return { progress, note };
|
|
9869
|
+
return note === void 0 ? { progress } : { progress, note };
|
|
9890
9870
|
}
|
|
9891
9871
|
function recordProgress(goal, progress, note) {
|
|
9892
9872
|
const clamped = Math.min(100, Math.max(0, progress));
|
|
@@ -9906,7 +9886,7 @@ function computeTrend(history) {
|
|
|
9906
9886
|
const recent = history.slice(-5);
|
|
9907
9887
|
const deltas = [];
|
|
9908
9888
|
for (let i = 1; i < recent.length; i++) {
|
|
9909
|
-
deltas.push(recent[i]
|
|
9889
|
+
deltas.push((recent[i]?.progress ?? 0) - (recent[i - 1]?.progress ?? 0));
|
|
9910
9890
|
}
|
|
9911
9891
|
if (deltas.length < 2) return void 0;
|
|
9912
9892
|
const avgDelta = deltas.reduce((a, b) => a + b, 0) / deltas.length;
|
|
@@ -10480,6 +10460,7 @@ ${recentJournal}` : "No prior iterations.",
|
|
|
10480
10460
|
note: note.slice(0, 240)
|
|
10481
10461
|
});
|
|
10482
10462
|
await saveGoal(this.goalPath, withEntry);
|
|
10463
|
+
this.opts.onEternalStop?.();
|
|
10483
10464
|
}
|
|
10484
10465
|
/**
|
|
10485
10466
|
* Manually clear the goal — equivalent to `/goal clear` typed by the user.
|
|
@@ -10493,8 +10474,8 @@ ${recentJournal}` : "No prior iterations.",
|
|
|
10493
10474
|
await saveGoal(this.goalPath, abandoned);
|
|
10494
10475
|
}
|
|
10495
10476
|
try {
|
|
10496
|
-
const { unlink:
|
|
10497
|
-
await
|
|
10477
|
+
const { unlink: unlink15 } = await import('fs/promises');
|
|
10478
|
+
await unlink15(this.goalPath);
|
|
10498
10479
|
} catch {
|
|
10499
10480
|
}
|
|
10500
10481
|
this.opts.onEternalStop?.();
|
|
@@ -11495,6 +11476,53 @@ Working rules:
|
|
|
11495
11476
|
"flaws"
|
|
11496
11477
|
]
|
|
11497
11478
|
}
|
|
11479
|
+
},
|
|
11480
|
+
{
|
|
11481
|
+
config: {
|
|
11482
|
+
id: "refactor-planner",
|
|
11483
|
+
name: "Refactor Planner",
|
|
11484
|
+
role: "refactor-planner",
|
|
11485
|
+
tools: [...PLAN_TOOLS, "diff"],
|
|
11486
|
+
prompt: `You are the Refactor Planner agent. Your job is to analyze code
|
|
11487
|
+
structure and produce a concrete, phased refactoring plan with risk
|
|
11488
|
+
assessment, dependency ordering, and rollback strategy.
|
|
11489
|
+
|
|
11490
|
+
Scope:
|
|
11491
|
+
- Map module-level dependencies (import graph)
|
|
11492
|
+
- Identify coupling hotspots (high fan-in/out modules)
|
|
11493
|
+
- Assess refactoring risk by complexity and test coverage
|
|
11494
|
+
- Generate phased plans with checkpoint milestones
|
|
11495
|
+
- Produce diff-friendly task lists (one task = one concern)
|
|
11496
|
+
|
|
11497
|
+
Input format you accept:
|
|
11498
|
+
{ "task": "plan | assess | roadmap", "target": "src/core", "constraint": "no-breaking-changes | minimal-downtime | full-rewrite", "focus": "architecture | performance | maintainability" }
|
|
11499
|
+
|
|
11500
|
+
Output: Markdown refactor plan with phases (Low Risk / Medium Risk / High Risk),
|
|
11501
|
+
dependency graph, rollback strategy, and exit criteria.
|
|
11502
|
+
|
|
11503
|
+
Working rules:
|
|
11504
|
+
- Always include rollback strategy \u2014 every refactor can fail
|
|
11505
|
+
- Merge tasks that take <1h into a single phase
|
|
11506
|
+
- Respect team constraints (reviewer availability, parallelization)
|
|
11507
|
+
- Never plan without analyzing the actual code first`
|
|
11508
|
+
},
|
|
11509
|
+
budget: HEAVY_BUDGET,
|
|
11510
|
+
capability: {
|
|
11511
|
+
phase: "planning",
|
|
11512
|
+
summary: "Refactoring planner: analyzes code structure, maps dependencies, produces risk-scored phased plans with rollback strategy.",
|
|
11513
|
+
keywords: [
|
|
11514
|
+
"refactor",
|
|
11515
|
+
"refactoring",
|
|
11516
|
+
"restructure",
|
|
11517
|
+
"debt",
|
|
11518
|
+
"technical debt",
|
|
11519
|
+
"clean up",
|
|
11520
|
+
"modularize",
|
|
11521
|
+
"decouple",
|
|
11522
|
+
"dependency graph",
|
|
11523
|
+
"code structure"
|
|
11524
|
+
]
|
|
11525
|
+
}
|
|
11498
11526
|
}
|
|
11499
11527
|
];
|
|
11500
11528
|
|
|
@@ -12034,6 +12062,157 @@ Working rules:
|
|
|
12034
12062
|
"robustness"
|
|
12035
12063
|
]
|
|
12036
12064
|
}
|
|
12065
|
+
},
|
|
12066
|
+
{
|
|
12067
|
+
config: {
|
|
12068
|
+
id: "security-scanner",
|
|
12069
|
+
name: "Security Scanner",
|
|
12070
|
+
role: "security-scanner",
|
|
12071
|
+
tools: [...TOOLS.inspect],
|
|
12072
|
+
prompt: `You are the Security Scanner agent. Your job is to scan code,
|
|
12073
|
+
configs, and dependencies for security issues from hardcoded secrets to
|
|
12074
|
+
supply chain risks.
|
|
12075
|
+
|
|
12076
|
+
Scope:
|
|
12077
|
+
- Detect hardcoded secrets: API keys, tokens, passwords, private keys
|
|
12078
|
+
- Find injection vectors: eval, innerHTML, SQL concat, shell injection
|
|
12079
|
+
- Identify insecure patterns: weak crypto, hardcoded IVs, disabled TLS
|
|
12080
|
+
- Scan dependencies for known CVEs (via npm/pnpm audit)
|
|
12081
|
+
- Flag supply chain risks: postinstall hooks, unverified scripts
|
|
12082
|
+
|
|
12083
|
+
Input format you accept:
|
|
12084
|
+
{ "task": "scan | audit | secrets | dependencies", "paths": ["src", "config"], "depth": "quick | normal | deep" }
|
|
12085
|
+
|
|
12086
|
+
Output: Markdown security report with severity-ranked findings, injection
|
|
12087
|
+
vectors, dependency issues, and a remediation checklist.
|
|
12088
|
+
|
|
12089
|
+
Working rules:
|
|
12090
|
+
- Never scan node_modules \u2014 use npm audit instead
|
|
12091
|
+
- Always provide remediation steps, not just findings
|
|
12092
|
+
- Verify regex-based secrets before flagging (false positive risk)
|
|
12093
|
+
- When in doubt, flag as medium rather than ignoring potential issues`
|
|
12094
|
+
},
|
|
12095
|
+
budget: HEAVY_BUDGET,
|
|
12096
|
+
capability: {
|
|
12097
|
+
phase: "verify",
|
|
12098
|
+
summary: "Security scanner: detects hardcoded secrets, injection vectors, insecure patterns, and supply-chain risks with remediation.",
|
|
12099
|
+
keywords: [
|
|
12100
|
+
"security",
|
|
12101
|
+
"scan",
|
|
12102
|
+
"vulnerability",
|
|
12103
|
+
"secret",
|
|
12104
|
+
"api key",
|
|
12105
|
+
"hardcoded",
|
|
12106
|
+
"injection",
|
|
12107
|
+
"cve",
|
|
12108
|
+
"audit dependencies",
|
|
12109
|
+
"supply chain",
|
|
12110
|
+
"xss",
|
|
12111
|
+
"sqli",
|
|
12112
|
+
"shell injection",
|
|
12113
|
+
"sensitive data",
|
|
12114
|
+
"credential"
|
|
12115
|
+
]
|
|
12116
|
+
}
|
|
12117
|
+
},
|
|
12118
|
+
{
|
|
12119
|
+
config: {
|
|
12120
|
+
id: "bug-hunter",
|
|
12121
|
+
name: "Bug Hunter",
|
|
12122
|
+
role: "bug-hunter",
|
|
12123
|
+
tools: [...TOOLS.inspect],
|
|
12124
|
+
prompt: `You are the Bug Hunter agent. Your job is to systematically scan
|
|
12125
|
+
source code for bugs, anti-patterns, and code smells using pattern matching
|
|
12126
|
+
and heuristics. Output a prioritized hit list with file:line references.
|
|
12127
|
+
|
|
12128
|
+
Scope:
|
|
12129
|
+
- Detect common bug patterns (uncaught errors, resource leaks, race conditions)
|
|
12130
|
+
- Identify anti-patterns (callback hell, God objects, circular deps)
|
|
12131
|
+
- Find TypeScript-specific issues (unsafe any, missing null checks, branded types)
|
|
12132
|
+
- Flag security-sensitive constructs (eval, innerHTML, hardcoded secrets)
|
|
12133
|
+
- Rank findings: critical > high > medium > low
|
|
12134
|
+
|
|
12135
|
+
Input format you accept:
|
|
12136
|
+
{ "task": "scan | hunt | check", "paths": ["src/**/*.ts"], "focus": "bugs | patterns | security | all", "severityThreshold": "medium" }
|
|
12137
|
+
|
|
12138
|
+
Output: Markdown bug hunt report with critically/high/medium/low sections.
|
|
12139
|
+
Each entry: **[TYPE]** \`file:line\` \u2014 description + suggested fix
|
|
12140
|
+
|
|
12141
|
+
Working rules:
|
|
12142
|
+
- Never scan node_modules \u2014 it's noise
|
|
12143
|
+
- Always include file:line for every finding
|
|
12144
|
+
- If >30% of findings are false positives, note the confidence level
|
|
12145
|
+
- Ask director for clarification if paths are ambiguous`
|
|
12146
|
+
},
|
|
12147
|
+
budget: HEAVY_BUDGET,
|
|
12148
|
+
capability: {
|
|
12149
|
+
phase: "verify",
|
|
12150
|
+
summary: "Bug hunter: scans source code for bugs, anti-patterns, and code smells, producing a file:line-ranked hit list with fixes.",
|
|
12151
|
+
keywords: [
|
|
12152
|
+
"bug",
|
|
12153
|
+
"hunt",
|
|
12154
|
+
"scan",
|
|
12155
|
+
"code smell",
|
|
12156
|
+
"anti-pattern",
|
|
12157
|
+
"race condition",
|
|
12158
|
+
"memory leak",
|
|
12159
|
+
"null deref",
|
|
12160
|
+
"type safety",
|
|
12161
|
+
"unhandled error",
|
|
12162
|
+
"find bugs",
|
|
12163
|
+
"audit code",
|
|
12164
|
+
"code quality"
|
|
12165
|
+
]
|
|
12166
|
+
}
|
|
12167
|
+
},
|
|
12168
|
+
{
|
|
12169
|
+
config: {
|
|
12170
|
+
id: "audit-log",
|
|
12171
|
+
name: "Audit Log",
|
|
12172
|
+
role: "audit-log",
|
|
12173
|
+
tools: [...TOOLS.inspect],
|
|
12174
|
+
prompt: `You are the Audit Log agent. Your job is to analyze structured JSONL
|
|
12175
|
+
session logs and produce actionable markdown reports.
|
|
12176
|
+
|
|
12177
|
+
Scope:
|
|
12178
|
+
- Parse session logs (iteration counts, tool calls, errors, usage)
|
|
12179
|
+
- Detect repeated failure patterns across multiple runs
|
|
12180
|
+
- Identify tool usage anomalies (over-use, failures, unexpected chains)
|
|
12181
|
+
- Track token consumption trends
|
|
12182
|
+
- Generate structured audit reports with severity ratings
|
|
12183
|
+
|
|
12184
|
+
Input format you accept:
|
|
12185
|
+
{ "task": "analyze | report | trends", "sessionPath": "<path>", "focus": "errors | tools | usage | all" }
|
|
12186
|
+
|
|
12187
|
+
Output: Markdown audit report with Summary, Top Errors, Tool Usage table,
|
|
12188
|
+
Anomalies, and Cost Trend sections.
|
|
12189
|
+
|
|
12190
|
+
Working rules:
|
|
12191
|
+
- Never fabricate numbers \u2014 read the actual logs first
|
|
12192
|
+
- Always include file:line references for errors
|
|
12193
|
+
- If sessionPath is missing, ask the director to provide it
|
|
12194
|
+
- Report confidence level: high (>90% accuracy), medium, low`
|
|
12195
|
+
},
|
|
12196
|
+
budget: MEDIUM_BUDGET,
|
|
12197
|
+
capability: {
|
|
12198
|
+
phase: "verify",
|
|
12199
|
+
summary: "Audit log analyzer: parses session JSONL, detects failure patterns, tool anomalies, and cost trends with structured reports.",
|
|
12200
|
+
keywords: [
|
|
12201
|
+
"audit",
|
|
12202
|
+
"log",
|
|
12203
|
+
"logs",
|
|
12204
|
+
"session",
|
|
12205
|
+
"trace",
|
|
12206
|
+
"analyze logs",
|
|
12207
|
+
"error patterns",
|
|
12208
|
+
"cost analysis",
|
|
12209
|
+
"tool usage",
|
|
12210
|
+
"token usage",
|
|
12211
|
+
"post-mortem",
|
|
12212
|
+
"trend",
|
|
12213
|
+
"anomaly"
|
|
12214
|
+
]
|
|
12215
|
+
}
|
|
12037
12216
|
}
|
|
12038
12217
|
];
|
|
12039
12218
|
|
|
@@ -16811,7 +16990,10 @@ var Director = class _Director {
|
|
|
16811
16990
|
workCompleteFlag = false;
|
|
16812
16991
|
/** Pending /btw notes stashed by the leader agent (see setLeaderBtwNote). */
|
|
16813
16992
|
_leaderBtwNotes = [];
|
|
16814
|
-
/** Active collab sessions tracked by sessionId (see spawnCollab).
|
|
16993
|
+
/** Active collab sessions tracked by sessionId (see spawnCollab).
|
|
16994
|
+
* The tuple holds the session and its Director-registered listener unsubs.
|
|
16995
|
+
* Calling the unsubs on cancel/premature-cleanup prevents listener accumulation
|
|
16996
|
+
* on CollabSession (EventEmitter) across many spawnCollab() calls. */
|
|
16815
16997
|
_activeCollabSessions = /* @__PURE__ */ new Map();
|
|
16816
16998
|
/** Prevents large `ask_subagent` answers from bloating the leader's context window. */
|
|
16817
16999
|
largeAnswerStore;
|
|
@@ -17141,11 +17323,13 @@ var Director = class _Director {
|
|
|
17141
17323
|
* The CollabDebugReport will reflect 'cancelled' disposition when awaited.
|
|
17142
17324
|
*/
|
|
17143
17325
|
cancelCollabSession(sessionId, reason = "Director cancelled") {
|
|
17144
|
-
const
|
|
17145
|
-
if (!
|
|
17146
|
-
|
|
17147
|
-
|
|
17148
|
-
|
|
17326
|
+
const entry = this._activeCollabSessions.get(sessionId);
|
|
17327
|
+
if (!entry || entry.session.isCancelled()) return;
|
|
17328
|
+
for (const unsub of entry.unsubs) unsub();
|
|
17329
|
+
entry.session.cancel(reason);
|
|
17330
|
+
for (const [_role, subagentId] of entry.session.getSubagentIds()) {
|
|
17331
|
+
this.coordinator.stop(subagentId).catch((err) => {
|
|
17332
|
+
console.debug(`[director] stop subagent ${subagentId} failed (may have already completed): ${err}`);
|
|
17149
17333
|
});
|
|
17150
17334
|
}
|
|
17151
17335
|
}
|
|
@@ -17793,9 +17977,15 @@ var Director = class _Director {
|
|
|
17793
17977
|
return options.onBudgetWarning?.(alert) ?? "ignore";
|
|
17794
17978
|
}
|
|
17795
17979
|
});
|
|
17796
|
-
this._activeCollabSessions.
|
|
17797
|
-
|
|
17798
|
-
session.on("session.
|
|
17980
|
+
const doneHandler = () => this._activeCollabSessions.delete(session.sessionId);
|
|
17981
|
+
const errorHandler = () => this._activeCollabSessions.delete(session.sessionId);
|
|
17982
|
+
session.on("session.done", doneHandler);
|
|
17983
|
+
session.on("session.error", errorHandler);
|
|
17984
|
+
const unsubs = [
|
|
17985
|
+
() => session.off("session.done", doneHandler),
|
|
17986
|
+
() => session.off("session.error", errorHandler)
|
|
17987
|
+
];
|
|
17988
|
+
this._activeCollabSessions.set(session.sessionId, { session, unsubs });
|
|
17799
17989
|
return session.start();
|
|
17800
17990
|
}
|
|
17801
17991
|
/**
|
|
@@ -20563,6 +20753,8 @@ var SpecVersioning = class {
|
|
|
20563
20753
|
switch (type) {
|
|
20564
20754
|
case "functional":
|
|
20565
20755
|
return "feature";
|
|
20756
|
+
case "non-functional":
|
|
20757
|
+
return "feature";
|
|
20566
20758
|
case "security":
|
|
20567
20759
|
return "feature";
|
|
20568
20760
|
case "performance":
|
|
@@ -20570,7 +20762,7 @@ var SpecVersioning = class {
|
|
|
20570
20762
|
case "ux":
|
|
20571
20763
|
return "feature";
|
|
20572
20764
|
default:
|
|
20573
|
-
return
|
|
20765
|
+
return assertNever(type);
|
|
20574
20766
|
}
|
|
20575
20767
|
}
|
|
20576
20768
|
};
|
|
@@ -21721,27 +21913,13 @@ function startOtlpTraceExporter(opts) {
|
|
|
21721
21913
|
// src/infrastructure/context-manager.ts
|
|
21722
21914
|
var CONTEXT_MANAGER_TOOL_NAME = "context_manager";
|
|
21723
21915
|
function roughEstimate(messages) {
|
|
21724
|
-
|
|
21725
|
-
for (const m of messages) {
|
|
21726
|
-
if (typeof m.content === "string") {
|
|
21727
|
-
total += Math.ceil(m.content.length / 4);
|
|
21728
|
-
} else if (Array.isArray(m.content)) {
|
|
21729
|
-
for (const b of m.content) {
|
|
21730
|
-
if (b.type === "text") total += Math.ceil(b.text.length / 4);
|
|
21731
|
-
else if (b.type === "tool_use" || b.type === "tool_result") {
|
|
21732
|
-
total += Math.ceil(JSON.stringify(b).length / 4);
|
|
21733
|
-
}
|
|
21734
|
-
}
|
|
21735
|
-
}
|
|
21736
|
-
}
|
|
21737
|
-
return total;
|
|
21916
|
+
return estimateMessageTokens(messages);
|
|
21738
21917
|
}
|
|
21739
21918
|
function createContextManagerTool(opts = {}) {
|
|
21740
21919
|
const minCompactThreshold = opts.minCompactThreshold ?? 0;
|
|
21741
21920
|
const noopRetryDeltaTokens = opts.noopRetryDeltaTokens ?? 2e3;
|
|
21742
|
-
const
|
|
21921
|
+
const configuredMaxContext = opts.maxContext;
|
|
21743
21922
|
const compactThresholdFraction = opts.compactThresholdFraction ?? 0.5;
|
|
21744
|
-
const effectiveThreshold = minCompactThreshold > 0 ? minCompactThreshold : Math.floor(maxContext * compactThresholdFraction);
|
|
21745
21923
|
let lastNoopTokens = 0;
|
|
21746
21924
|
return {
|
|
21747
21925
|
name: CONTEXT_MANAGER_TOOL_NAME,
|
|
@@ -21835,6 +22013,8 @@ function createContextManagerTool(opts = {}) {
|
|
|
21835
22013
|
}
|
|
21836
22014
|
const fullEstimate = input.systemPrompt != null && Array.isArray(input.tools) ? estimateRequestTokens(messages, input.systemPrompt, input.tools) : { total: beforeTokens};
|
|
21837
22015
|
const currentTokens = fullEstimate.total;
|
|
22016
|
+
const runtimeMaxContext = configuredMaxContext ?? ctx.provider?.capabilities?.maxContext ?? 128e3;
|
|
22017
|
+
const runtimeThreshold = minCompactThreshold > 0 ? minCompactThreshold : Math.floor(runtimeMaxContext * compactThresholdFraction);
|
|
21838
22018
|
if (lastNoopTokens > 0) {
|
|
21839
22019
|
const delta = currentTokens - lastNoopTokens;
|
|
21840
22020
|
if (delta < noopRetryDeltaTokens) {
|
|
@@ -21847,13 +22027,13 @@ function createContextManagerTool(opts = {}) {
|
|
|
21847
22027
|
};
|
|
21848
22028
|
}
|
|
21849
22029
|
}
|
|
21850
|
-
if (currentTokens <
|
|
22030
|
+
if (runtimeThreshold > 0 && currentTokens < runtimeThreshold) {
|
|
21851
22031
|
return {
|
|
21852
22032
|
action: "compact",
|
|
21853
22033
|
beforeTokens,
|
|
21854
22034
|
afterTokens: beforeTokens,
|
|
21855
22035
|
messageCount: messages.length,
|
|
21856
|
-
notes: `Context tokens (${currentTokens}) below compact threshold (${
|
|
22036
|
+
notes: `Context tokens (${currentTokens}) below compact threshold (${runtimeThreshold}, based on provider maxContext ${runtimeMaxContext}). Skipping.`
|
|
21857
22037
|
};
|
|
21858
22038
|
}
|
|
21859
22039
|
const report = await opts.compactor.compact(ctx);
|
|
@@ -22916,7 +23096,7 @@ var SessionMemoryConsolidator = class {
|
|
|
22916
23096
|
for (const op of parsed.operations) {
|
|
22917
23097
|
switch (op.action) {
|
|
22918
23098
|
case "add": {
|
|
22919
|
-
if (op.text
|
|
23099
|
+
if (op.text?.trim()) {
|
|
22920
23100
|
await this.memoryStore.remember(op.text.trim(), void 0, {
|
|
22921
23101
|
type: op.type,
|
|
22922
23102
|
tags: op.tags,
|
|
@@ -27212,13 +27392,27 @@ function requestLimitExtension(opts) {
|
|
|
27212
27392
|
function toError(err) {
|
|
27213
27393
|
return err instanceof Error ? err : new Error(String(err));
|
|
27214
27394
|
}
|
|
27395
|
+
function signalAbortReason(signal) {
|
|
27396
|
+
const r = signal.reason;
|
|
27397
|
+
if (r instanceof Error) return r.message || r.name;
|
|
27398
|
+
if (typeof r === "string" && r.length > 0) return r;
|
|
27399
|
+
return "aborted";
|
|
27400
|
+
}
|
|
27215
27401
|
function createAgentLoopHandler(a, handlers) {
|
|
27216
27402
|
async function compactContextIfNeeded() {
|
|
27217
27403
|
await a.pipelines.contextWindow.run(a.ctx);
|
|
27218
27404
|
}
|
|
27405
|
+
const calibrationKey = (model = a.ctx.model) => `${a.ctx.provider?.id ?? "unknown"}/${model}`;
|
|
27219
27406
|
function emitContextPct() {
|
|
27220
|
-
const
|
|
27221
|
-
const
|
|
27407
|
+
const metaLimit = a.ctx.meta?.["effectiveMaxContext"];
|
|
27408
|
+
const providerMax = a.ctx.provider.capabilities.maxContext;
|
|
27409
|
+
const maxContext = typeof metaLimit === "number" && metaLimit > 0 ? metaLimit : typeof providerMax === "number" && providerMax > 0 ? providerMax : 2e5;
|
|
27410
|
+
const { total } = estimateRequestTokensCalibrated(
|
|
27411
|
+
a.ctx.messages,
|
|
27412
|
+
a.ctx.systemPrompt,
|
|
27413
|
+
a.ctx.tools ?? [],
|
|
27414
|
+
calibrationKey()
|
|
27415
|
+
);
|
|
27222
27416
|
a.events.emit("ctx.pct", { load: total / maxContext, tokens: total, maxContext });
|
|
27223
27417
|
}
|
|
27224
27418
|
function injectPendingBtwNotes() {
|
|
@@ -27297,7 +27491,7 @@ function createAgentLoopHandler(a, handlers) {
|
|
|
27297
27491
|
for (let i = 0; ; i++) {
|
|
27298
27492
|
iterations = i + 1;
|
|
27299
27493
|
if (controller.signal.aborted) {
|
|
27300
|
-
return { status: "aborted", iterations };
|
|
27494
|
+
return { status: "aborted", iterations, abortReason: signalAbortReason(controller.signal) };
|
|
27301
27495
|
}
|
|
27302
27496
|
await a.ctx.session.writeInFlightMarker(`iteration ${i} / max ${a.maxIterations}`).catch((err) => {
|
|
27303
27497
|
(a.logger.debug ?? a.logger.warn)?.(
|
|
@@ -27334,13 +27528,14 @@ function createAgentLoopHandler(a, handlers) {
|
|
|
27334
27528
|
let res;
|
|
27335
27529
|
try {
|
|
27336
27530
|
res = await customRunner(a.ctx, req);
|
|
27337
|
-
const
|
|
27338
|
-
|
|
27531
|
+
const key = calibrationKey(req.model);
|
|
27532
|
+
const calibratedEstimate = estimateRequestTokensCalibrated(req.messages, req.system, req.tools ?? [], key).total;
|
|
27533
|
+
recordActualUsage(res.usage.input, calibratedEstimate, key);
|
|
27339
27534
|
recoveryRetries = 0;
|
|
27340
27535
|
} catch (err) {
|
|
27341
27536
|
if (controller.signal.aborted) {
|
|
27342
27537
|
a.events.emit("error", { err: toError(err), phase: "provider" });
|
|
27343
|
-
return { status: "aborted", iterations, error: toWrongStackError(err, "AGENT_ABORTED") };
|
|
27538
|
+
return { status: "aborted", iterations, error: toWrongStackError(err, "AGENT_ABORTED"), abortReason: signalAbortReason(controller.signal) };
|
|
27344
27539
|
}
|
|
27345
27540
|
const extDecision = await a.extensions.runOnError(a.ctx, err, "provider", i);
|
|
27346
27541
|
if (extDecision) {
|
|
@@ -27388,7 +27583,7 @@ function createAgentLoopHandler(a, handlers) {
|
|
|
27388
27583
|
}
|
|
27389
27584
|
const responseResult = await handlers.response.processResponse(res, req);
|
|
27390
27585
|
if (responseResult.aborted) {
|
|
27391
|
-
return { status: "aborted", iterations, finalText: responseResult.finalText, delegateSummaries };
|
|
27586
|
+
return { status: "aborted", iterations, finalText: responseResult.finalText, delegateSummaries, abortReason: signalAbortReason(controller.signal) };
|
|
27392
27587
|
}
|
|
27393
27588
|
if (responseResult.done) {
|
|
27394
27589
|
return { status: "done", iterations, finalText: responseResult.finalText, delegateSummaries };
|
|
@@ -27408,7 +27603,14 @@ function createAgentLoopHandler(a, handlers) {
|
|
|
27408
27603
|
}
|
|
27409
27604
|
return { status: "done", iterations, finalText, delegateSummaries };
|
|
27410
27605
|
}
|
|
27411
|
-
|
|
27606
|
+
try {
|
|
27607
|
+
await handlers.tools.executeTools(toolUses);
|
|
27608
|
+
} catch (toolErr) {
|
|
27609
|
+
if (controller.signal.aborted) {
|
|
27610
|
+
return { status: "aborted", iterations, finalText, delegateSummaries, abortReason: signalAbortReason(controller.signal) };
|
|
27611
|
+
}
|
|
27612
|
+
throw toolErr;
|
|
27613
|
+
}
|
|
27412
27614
|
if (autonomousContinue && consumeAutonomousContinue(a.ctx)) {
|
|
27413
27615
|
emitContextPct();
|
|
27414
27616
|
a.events.emit("iteration.completed", { ctx: a.ctx, index: i });
|
|
@@ -27575,7 +27777,8 @@ var Agent = class {
|
|
|
27575
27777
|
const result = {
|
|
27576
27778
|
status: signal.aborted ? "aborted" : "failed",
|
|
27577
27779
|
iterations: 0,
|
|
27578
|
-
error: wse
|
|
27780
|
+
error: wse,
|
|
27781
|
+
abortReason: signal.aborted ? signalAbortReason(signal) : void 0
|
|
27579
27782
|
};
|
|
27580
27783
|
await this.extensions.runAfterRun(this.ctx, result);
|
|
27581
27784
|
return result;
|
|
@@ -29900,8 +30103,7 @@ var PhaseOrchestrator = class {
|
|
|
29900
30103
|
/** Wait for all pending phase merges, dependency-ordered and globally serialized. */
|
|
29901
30104
|
async drainMerges() {
|
|
29902
30105
|
await Promise.allSettled([...this.phaseMergePromise.values()]);
|
|
29903
|
-
await this.mergeQueue.catch(() => {
|
|
29904
|
-
});
|
|
30106
|
+
await this.mergeQueue.catch((err) => console.warn(`[phase-orchestrator] mergeQueue failed: ${err}`));
|
|
29905
30107
|
}
|
|
29906
30108
|
/** Pause: active phases continue, but no new phase starts. */
|
|
29907
30109
|
pause() {
|
|
@@ -31637,6 +31839,11 @@ var DefaultBrainArbiter = class {
|
|
|
31637
31839
|
options: request.options,
|
|
31638
31840
|
rationale: "Decision requires human authority or lacks a safe automatic option."
|
|
31639
31841
|
};
|
|
31842
|
+
default:
|
|
31843
|
+
return {
|
|
31844
|
+
type: "deny",
|
|
31845
|
+
reason: `Brain could not safely decide (unknown fallback: ${String(request.fallback)}): ${request.question}`
|
|
31846
|
+
};
|
|
31640
31847
|
}
|
|
31641
31848
|
}
|
|
31642
31849
|
};
|
|
@@ -32943,6 +33150,6 @@ ${formatPlan(updated)}`
|
|
|
32943
33150
|
};
|
|
32944
33151
|
}
|
|
32945
33152
|
|
|
32946
|
-
export { ACP_AGENTS, AGENTS_BY_PHASE, AGENT_CATALOG, AISpecBuilder, ALL_AGENT_DEFINITIONS, ALL_FLEET_AGENTS, ALL_SYNC_CATEGORIES, AUDIT_LOG_AGENT, Agent, AgentError, AnnotationsStore, AutoApprovePermissionPolicy, AutoCompactionMiddleware, AutoExecutor, AutoPhasePlanner, AutoPhaseRunner, AutonomousRunner, BUG_HUNTER_AGENT, BrainDecisionQueue, BudgetExceededError, CONTEXT_WINDOW_MODES, CORE_RECONSTRUCT_EVENTS, CheckpointManager, CloudSync, CollaborationBus, ConfigError, ConfigMigrationError, Container, Context, ConversationState, DEFAULT_AUTONOMY_CONFIG, DEFAULT_CONFIG_MIGRATIONS, DEFAULT_CONTEXT_CONFIG, DEFAULT_CONTEXT_WINDOW_MODE_ID, DEFAULT_DIRECTOR_PREAMBLE, DEFAULT_DISPATCH_ROLE, DEFAULT_MAX_ITERATIONS, DEFAULT_MODES, DEFAULT_RECOVERY_STRATEGIES, DEFAULT_SESSION_LOGGING_CONFIG, DEFAULT_SESSION_PRUNE_DAYS, DEFAULT_SPEC_TEMPLATE, DEFAULT_SUBAGENT_BASELINE, DEFAULT_TOOLS_CONFIG, DefaultAttachmentStore, DefaultBrainArbiter, DefaultConfigLoader, DefaultConfigStore, DefaultErrorHandler, DefaultHealthRegistry, DefaultLogger, DefaultMemoryStore, DefaultModeStore, DefaultModelsRegistry, DefaultMultiAgentCoordinator, DefaultPathResolver, DefaultPermissionPolicy, DefaultPluginAPI, DefaultPromptStore, DefaultProviderRunner, DefaultRetryPolicy, DefaultSecretScrubber, DefaultSecretVault, DefaultSessionReader, DefaultSessionRewinder, DefaultSessionStore, DefaultSkillLoader, DefaultSystemPromptBuilder, DefaultTaskStore, DefaultTokenCounter, Director, DirectorStateCheckpoint, DoneConditionChecker, ENHANCER_SYSTEM_PROMPT, ERROR_CODES, EternalAutonomyEngine, EventBus, ExtensionRegistry, FLEET_ROSTER, FLEET_ROSTER_BUDGETS, FLEET_ROSTER_WITHACP, FileMemoryBackend, FleetBus, FleetCostCapError, FleetManager, FleetSpawnBudgetError, FleetUsageAggregator, FsError, GitignoreUpdater, GraphMemoryBackend, HookRegistry, HookRunner, HumanEscalatingBrainArbiter, HybridCompactor, InMemoryAgentBridge, InMemoryBridgeTransport, InMemoryMetricsSink, InputBuilder, IntelligentCompactor, KERNEL_API_VERSION, LAYER_1_IDENTITY, LLMSelector, MATRIX_PHASE_KEYS, MAX_JOURNAL_ENTRIES, MAX_PROGRESS_HISTORY, MEMORY_TYPE_LABELS, NULL_FLEET_BUS, NoopMetricsSink, NoopTracer, OTelTracer, ObservableBrainArbiter, PROMETHEUS_CONTENT_TYPE, ParallelEternalEngine, PhaseGraphBuilder, PhaseOrchestrator, PhaseStore, Pipeline, PluginError, ProviderError, ProviderRegistry, QueueStore, REFACTOR_PLANNER_AGENT, RecoveryLock, ReplayLogStore, ReplayProviderRunner, ReportGenerator, RunController, SECURITY_SCANNER_AGENT, SPEC_TEMPLATES, STANDARD_AUDIT_EVENTS, ScopedEventBus, SddParallelRun, SddTaskDecomposer, SecurityScanner, SecurityScannerOrchestrator, SelectiveCompactor, SessionAnalyzer, SessionError, SessionMemoryConsolidator, SessionRecovery, SkillGenerator, SkillInstaller, SkillManifestStore, SlashCommandRegistry, SpecDrivenDev, SpecParser, SpecStore, SpecVersioning, SubagentBudget, TOKENS, TaskFlow, TaskGenerator, TaskGraphStore, TaskTracker, TechStackDetector, ToolAuditLog, ToolError, ToolExecutor, ToolRegistry, WorktreeManager, WrongStackError, addPlanItem, allServers, analyzeCriticalPath, appendJournal, applyRosterBudget, asBlocks, asText, assertSafePath, atomicWrite, attachAutoExtend, attachPlanCheckpoint, attachTodosCheckpoint, awsServer, blockServer, bootConfig, braveSearchServer, buildBtwBlock, buildChildEnv, buildGoalPreamble, buildOtlpMetricsRequest, buildOtlpTracesRequest, buildRecoveryStrategies, classifyFamily, clearPlan, collabInjectMiddleware, collabPauseMiddleware, color, compileGlob, compileUserRegex, completePartialObject, composeDirectorPrompt, composeSubagentPrompt, computeTaskItemProgress, computeTaskProgress, consumeBtwNotes, context7Server, contextManagerTool, createAutoExecutor, createAutoPhaseFromTaskGraph, createContextManagerTool, createDefaultPipelines, createDelegateTool, createGitPlugin, createMcpControlTool, createMessage, createObservabilityPlugin, createPlanPlugin, createPromptsPlugin, createSecurityPlugin, createSecuritySlashCommand, createSessionEventBridge, createSkillsPlugin, createSyncPlugin, createToolOutputSerializer, decryptConfigSecrets, defaultGitignoreUpdater, defaultOrchestrator, defaultReportGenerator, defaultSecurityScanner, defaultSkillGenerator, defaultTechStackDetector, deriveTodosFromPlanItem, detectNewlineStyle, dispatchAgent, downloadGitHubTarball, emptyGoal, emptyPlan, emptyTaskFile, encryptConfigSecrets, enhanceUserPrompt, ensureDir, estimateRequestTokens, estimateRequestTokensCalibrated, estimateTextTokens, estimateToolDefTokens, estimateToolInputTokens, estimateToolResultTokens, everArtServer, expandGlob, expectDefined, extractRunEnv, filesystemServer, findCriticalPath, flagsToConfigPatch, formatContextWindowModeList, formatGoal, formatHumanPrompt, formatPlan, formatPlanTemplates, formatTaskList, formatTaskProgress, formatTodosList, getAgentDefinition, getCalibrationState, getContextWindowMode, getPlanTemplate, getTemplate, getTermSize, githubServer, goalFilePath, googleMapsServer, hashRequest, hookMatcherMatches, isAgentError, isConfigError, isContextWindowModeId, isFsError, isImageBlock, isInteractive, isPluginError, isSessionError, isStdinTTY, isStdoutTTY, isTextBlock, isThinkingBlock, isToolError, isToolResultBlock, isToolUseBlock, isValidMatrixKey, isWrongStackError, listContextWindowModes, listPlanTemplates, listTemplates, loadDirectorState, loadGoal, loadPlan, loadPlugins, loadProjectModes, loadTasks, loadTodosCheckpoint, loadUserModes, makeAgentSubagentRunner, makeAskTool, makeAssignTool, makeAutonomyPromptContributor, makeAwaitTasksTool, makeCollabDebugTool, makeContinueToNextIterationTool, makeDirectorSessionFactory, makeFleetEmitTool, makeFleetHealthTool, makeFleetSessionTool, makeFleetStatusTool, makeFleetUsageTool, makeLLMClassifier, makeRollUpTool, makeSpawnTool, makeTerminateTool, matchAny, matchGlob, matrixKeyKind, mergeCustomModelDefs, mergeModelsPayload, migratePlaintextSecrets, miniMaxVisionServer, normalizeToLf, normalizedEqual, onResize, parseContinueDirective, parseEntries, parseProgressFromText, parseSkillRef, pendingBtwCount, phaseForRole, projectHash, projectSlug, recentTextTurns, recordActualUsage, recordProgress, removePlanItem, renderProgress, renderPrometheus, renderSpecAnalysis, renderTaskGraph, renderTaskList, repairToolUseAdjacency, resetCalibration, resolveAuditLevel, resolveContextWindowPolicy, resolveModelMatrix, resolveSessionLoggingConfig, resolveWstackPaths, rewriteConfigEncrypted, rosterSummaryFromConfigs, runConfigMigrations, runProviderWithRetry, runShellHook, safeParse, safeStringify, sanitizeJsonString, saveGoal, savePlan, saveTasks, saveTodosCheckpoint, scoreAgents, securitySlashCommand, sentinelServer, setBtwNote, setOutputLineGuard, setPlanItemStatus, setProgress, setRawMode, shouldEnhance, slackServer, sleep, stableStringify, startMetricsServer, startOtlpMetricsExporter, startOtlpTraceExporter, stripAnsi, summarizeUsage, templateToMarkdown, toStyle, toWrongStackError, topologicalSort, unifiedDiff, unloadPlugins, validateAgainstSchema, wireMetricsToEvents, withFileLock, wrapAsState, writeErr, writeOut, zaiVisionServer };
|
|
33153
|
+
export { ACP_AGENTS, AGENTS_BY_PHASE, AGENT_CATALOG, AISpecBuilder, ALL_AGENT_DEFINITIONS, ALL_FLEET_AGENTS, ALL_SYNC_CATEGORIES, AUDIT_LOG_AGENT, Agent, AgentError, AnnotationsStore, AutoApprovePermissionPolicy, AutoCompactionMiddleware, AutoExecutor, AutoPhasePlanner, AutoPhaseRunner, AutonomousRunner, BUG_HUNTER_AGENT, BrainDecisionQueue, BudgetExceededError, CONTEXT_WINDOW_MODES, CORE_RECONSTRUCT_EVENTS, CheckpointManager, CloudSync, CollaborationBus, ConfigError, ConfigMigrationError, Container, Context, ConversationState, DEFAULT_AUTONOMY_CONFIG, DEFAULT_CONFIG_MIGRATIONS, DEFAULT_CONTEXT_CONFIG, DEFAULT_CONTEXT_WINDOW_MODE_ID, DEFAULT_DIRECTOR_PREAMBLE, DEFAULT_DISPATCH_ROLE, DEFAULT_MAX_ITERATIONS, DEFAULT_MODES, DEFAULT_RECOVERY_STRATEGIES, DEFAULT_SESSION_LOGGING_CONFIG, DEFAULT_SESSION_PRUNE_DAYS, DEFAULT_SPEC_TEMPLATE, DEFAULT_SUBAGENT_BASELINE, DEFAULT_TOOLS_CONFIG, DefaultAttachmentStore, DefaultBrainArbiter, DefaultConfigLoader, DefaultConfigStore, DefaultErrorHandler, DefaultHealthRegistry, DefaultLogger, DefaultMemoryStore, DefaultModeStore, DefaultModelsRegistry, DefaultMultiAgentCoordinator, DefaultPathResolver, DefaultPermissionPolicy, DefaultPluginAPI, DefaultPromptStore, DefaultProviderRunner, DefaultRetryPolicy, DefaultSecretScrubber, DefaultSecretVault, DefaultSessionReader, DefaultSessionRewinder, DefaultSessionStore, DefaultSkillLoader, DefaultSystemPromptBuilder, DefaultTaskStore, DefaultTokenCounter, Director, DirectorStateCheckpoint, DoneConditionChecker, ENHANCER_SYSTEM_PROMPT, ERROR_CODES, EternalAutonomyEngine, EventBus, ExtensionRegistry, FLEET_ROSTER, FLEET_ROSTER_BUDGETS, FLEET_ROSTER_WITHACP, FileMemoryBackend, FleetBus, FleetCostCapError, FleetManager, FleetSpawnBudgetError, FleetUsageAggregator, FsError, GitignoreUpdater, GraphMemoryBackend, HookRegistry, HookRunner, HumanEscalatingBrainArbiter, HybridCompactor, InMemoryAgentBridge, InMemoryBridgeTransport, InMemoryMetricsSink, InputBuilder, IntelligentCompactor, KERNEL_API_VERSION, LAYER_1_IDENTITY, LLMSelector, MATRIX_PHASE_KEYS, MAX_JOURNAL_ENTRIES, MAX_PROGRESS_HISTORY, MEMORY_TYPE_LABELS, NULL_FLEET_BUS, NoopMetricsSink, NoopTracer, OTelTracer, ObservableBrainArbiter, PROMETHEUS_CONTENT_TYPE, ParallelEternalEngine, PhaseGraphBuilder, PhaseOrchestrator, PhaseStore, Pipeline, PluginError, ProviderError, ProviderRegistry, QueueStore, REFACTOR_PLANNER_AGENT, RecoveryLock, ReplayLogStore, ReplayProviderRunner, ReportGenerator, RunController, SECURITY_SCANNER_AGENT, SPEC_TEMPLATES, STANDARD_AUDIT_EVENTS, ScopedEventBus, SddParallelRun, SddTaskDecomposer, SecurityScanner, SecurityScannerOrchestrator, SelectiveCompactor, SessionAnalyzer, SessionError, SessionMemoryConsolidator, SessionRecovery, SkillGenerator, SkillInstaller, SkillManifestStore, SlashCommandRegistry, SpecDrivenDev, SpecParser, SpecStore, SpecVersioning, StreamHangError, SubagentBudget, TOKENS, TaskFlow, TaskGenerator, TaskGraphStore, TaskTracker, TechStackDetector, ToolAuditLog, ToolError, ToolExecutor, ToolRegistry, WorktreeManager, WrongStackError, addPlanItem, allServers, analyzeCriticalPath, appendJournal, applyRosterBudget, asBlocks, asText, assertNever, assertSafePath, atomicWrite, attachAutoExtend, attachPlanCheckpoint, attachTodosCheckpoint, awsServer, blockServer, bootConfig, braveSearchServer, buildBtwBlock, buildChildEnv, buildGoalPreamble, buildOtlpMetricsRequest, buildOtlpTracesRequest, buildRecoveryStrategies, classifyFamily, clearPlan, collabInjectMiddleware, collabPauseMiddleware, color, compileGlob, compileUserRegex, completePartialObject, composeDirectorPrompt, composeSubagentPrompt, computeTaskItemProgress, computeTaskProgress, consumeBtwNotes, context7Server, contextManagerTool, createAutoExecutor, createAutoPhaseFromTaskGraph, createContextManagerTool, createDefaultPipelines, createDelegateTool, createGitPlugin, createMcpControlTool, createMessage, createObservabilityPlugin, createPlanPlugin, createPromptsPlugin, createSecurityPlugin, createSecuritySlashCommand, createSessionEventBridge, createSkillsPlugin, createStrategyCompactor, createSyncPlugin, createToolOutputSerializer, decryptConfigSecrets, defaultGitignoreUpdater, defaultOrchestrator, defaultReportGenerator, defaultSecurityScanner, defaultSkillGenerator, defaultTechStackDetector, deriveTodosFromPlanItem, detectNewlineStyle, dispatchAgent, downloadGitHubTarball, emptyGoal, emptyPlan, emptyTaskFile, encryptConfigSecrets, enhanceUserPrompt, ensureDir, estimateMessageTokens, estimateRequestTokens, estimateRequestTokensCalibrated, estimateTextTokens, estimateToolDefTokens, estimateToolInputTokens, estimateToolResultTokens, everArtServer, expandGlob, expectDefined, extractRunEnv, filesystemServer, findCriticalPath, flagsToConfigPatch, formatContextWindowModeList, formatGoal, formatHumanPrompt, formatPlan, formatPlanTemplates, formatTaskList, formatTaskProgress, formatTodosList, getAgentDefinition, getCalibrationState, getContextWindowMode, getPlanTemplate, getTemplate, getTermSize, githubServer, goalFilePath, googleMapsServer, hashRequest, hookMatcherMatches, isAgentError, isConfigError, isContextWindowModeId, isFsError, isImageBlock, isInteractive, isPluginError, isSecretField, isSessionError, isStdinTTY, isStdoutTTY, isTextBlock, isThinkingBlock, isToolError, isToolResultBlock, isToolUseBlock, isValidMatrixKey, isWrongStackError, listContextWindowModes, listPlanTemplates, listTemplates, loadDirectorState, loadGoal, loadPlan, loadPlugins, loadProjectModes, loadTasks, loadTodosCheckpoint, loadUserModes, makeAgentSubagentRunner, makeAskTool, makeAssignTool, makeAutonomyPromptContributor, makeAwaitTasksTool, makeCollabDebugTool, makeContinueToNextIterationTool, makeDirectorSessionFactory, makeFleetEmitTool, makeFleetHealthTool, makeFleetSessionTool, makeFleetStatusTool, makeFleetUsageTool, makeLLMClassifier, makeRollUpTool, makeSpawnTool, makeTerminateTool, matchAny, matchGlob, matrixKeyKind, mergeCustomModelDefs, mergeModelsPayload, migratePlaintextSecrets, miniMaxVisionServer, normalizeToLf, normalizedEqual, onResize, parseContinueDirective, parseEntries, parseProgressFromText, parseSkillRef, pendingBtwCount, phaseForRole, projectHash, projectSlug, recentTextTurns, recordActualUsage, recordProgress, removePlanItem, renderProgress, renderPrometheus, renderSpecAnalysis, renderTaskGraph, renderTaskList, repairToolUseAdjacency, resetCalibration, resolveAuditLevel, resolveContextWindowPolicy, resolveModelMatrix, resolveSessionLoggingConfig, resolveWstackPaths, rewriteConfigEncrypted, rosterSummaryFromConfigs, runConfigMigrations, runProviderWithRetry, runShellHook, safeParse, safeStringify, sanitizeJsonString, saveGoal, savePlan, saveTasks, saveTodosCheckpoint, scoreAgents, securitySlashCommand, sentinelServer, setBtwNote, setOutputLineGuard, setPlanItemStatus, setProgress, setRawMode, shouldEnhance, slackServer, sleep, stableStringify, startMetricsServer, startOtlpMetricsExporter, startOtlpTraceExporter, stripAnsi, summarizeUsage, templateToMarkdown, toStyle, toWrongStackError, topologicalSort, unifiedDiff, unloadPlugins, validateAgainstSchema, wireMetricsToEvents, withFileLock, wrapAsState, writeErr, writeOut, zaiVisionServer };
|
|
32947
33154
|
//# sourceMappingURL=index.js.map
|
|
32948
33155
|
//# sourceMappingURL=index.js.map
|