@cognipeer/agent-sdk 0.8.1 → 0.8.2

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/index.cjs CHANGED
@@ -52,7 +52,7 @@ function getTokenCounter() {
52
52
  function countApproxTokens(text) {
53
53
  return activeTokenCounter(text || "");
54
54
  }
55
- function extractMessageText2(m) {
55
+ function extractMessageText(m) {
56
56
  if (!m) return "";
57
57
  const parts = [];
58
58
  parts.push(m.role || "");
@@ -102,7 +102,7 @@ function extractMessageText2(m) {
102
102
  }
103
103
  function countMessagesTokens(messages) {
104
104
  if (!Array.isArray(messages) || messages.length === 0) return 0;
105
- const allText = messages.map(extractMessageText2).join("\n");
105
+ const allText = messages.map(extractMessageText).join("\n");
106
106
  return countApproxTokens(allText) + messages.length * 4;
107
107
  }
108
108
  var activeTokenCounter;
@@ -1088,7 +1088,35 @@ function buildConfigSnapshot(runtime) {
1088
1088
  sink: snapshotSink(runtime)
1089
1089
  };
1090
1090
  }
1091
- async function postTraceSession(url, headers, payload) {
1091
+ var TRACE_HTTP_MAX_ATTEMPTS = 4;
1092
+ var TRACE_HTTP_ATTEMPT_TIMEOUT_MS = 8e3;
1093
+ var TRACE_HTTP_RETRYABLE_STATUS = /* @__PURE__ */ new Set([404, 408, 425, 429, 500, 502, 503, 504]);
1094
+ var TRACE_HTTP_RETRY_BASE_MS = 250;
1095
+ var TRACE_HTTP_RETRY_MAX_MS = 4e3;
1096
+ var RetryableHttpError = class extends Error {
1097
+ constructor(status, message, retryAfterMs) {
1098
+ super(message);
1099
+ this.name = "RetryableHttpError";
1100
+ this.status = status;
1101
+ this.retryAfterMs = retryAfterMs;
1102
+ }
1103
+ };
1104
+ function traceSleep(ms) {
1105
+ return new Promise((resolve) => setTimeout(resolve, ms));
1106
+ }
1107
+ function traceBackoffDelay(attempt, baseMs, maxMs) {
1108
+ const exp = Math.min(maxMs, baseMs * 2 ** (attempt - 1));
1109
+ return Math.floor(Math.random() * exp);
1110
+ }
1111
+ function parseRetryAfterMs(headerValue) {
1112
+ if (!headerValue) return void 0;
1113
+ const seconds = Number(headerValue);
1114
+ if (Number.isFinite(seconds)) return Math.max(0, seconds * 1e3);
1115
+ const dateMs = Date.parse(headerValue);
1116
+ if (Number.isFinite(dateMs)) return Math.max(0, dateMs - Date.now());
1117
+ return void 0;
1118
+ }
1119
+ async function postJsonOnce(url, headers, body) {
1092
1120
  const fetchFn = typeof globalThis.fetch === "function" ? globalThis.fetch.bind(globalThis) : void 0;
1093
1121
  if (!fetchFn) {
1094
1122
  throw new Error("HTTP sink requires fetch to be available in this runtime.");
@@ -1097,135 +1125,71 @@ async function postTraceSession(url, headers, payload) {
1097
1125
  if (!Object.keys(finalHeaders).some((key) => key.toLowerCase() === "content-type")) {
1098
1126
  finalHeaders["content-type"] = "application/json";
1099
1127
  }
1128
+ const controller = new AbortController();
1129
+ const timer = setTimeout(() => controller.abort(), TRACE_HTTP_ATTEMPT_TIMEOUT_MS);
1130
+ let response;
1100
1131
  try {
1101
- const response = await fetchFn(url, {
1132
+ response = await fetchFn(url, {
1102
1133
  method: "POST",
1103
1134
  headers: finalHeaders,
1104
- body: JSON.stringify(payload)
1135
+ body: JSON.stringify(body),
1136
+ signal: controller.signal
1105
1137
  });
1106
- if (!response.ok) {
1107
- let responseText = "";
1108
- try {
1109
- responseText = await response.text();
1110
- } catch {
1111
- }
1112
- const statusLine = `HTTP ${response.status}${response.statusText ? ` ${response.statusText}` : ""}`;
1113
- const bodyPreview = responseText ? ` - ${responseText.slice(0, 200)}` : "";
1114
- const errorMsg = `${statusLine}${bodyPreview}`;
1115
- if (typeof console !== "undefined" && typeof console.error === "function") {
1116
- console.error("[Tracing] Error posting to", url, ":", errorMsg);
1117
- }
1118
- throw new Error(errorMsg);
1119
- }
1120
1138
  } catch (err) {
1121
- const errMsg = err instanceof Error ? err.message : String(err);
1122
- if (typeof console !== "undefined" && typeof console.error === "function") {
1123
- console.error("[Tracing] Failed to post:", errMsg);
1124
- }
1125
- throw err;
1139
+ const message2 = err instanceof Error ? err.message : String(err);
1140
+ throw new RetryableHttpError(0, `network error - ${message2}`);
1141
+ } finally {
1142
+ clearTimeout(timer);
1126
1143
  }
1127
- }
1128
- async function postStreamingSessionStart(baseUrl, headers, payload) {
1129
- const fetchFn = typeof globalThis.fetch === "function" ? globalThis.fetch.bind(globalThis) : void 0;
1130
- if (!fetchFn) {
1131
- throw new Error("HTTP sink requires fetch to be available in this runtime.");
1144
+ if (response.ok) return;
1145
+ let responseText = "";
1146
+ try {
1147
+ responseText = await response.text();
1148
+ } catch {
1132
1149
  }
1133
- const url = `${baseUrl.replace(/\/$/, "")}/stream/${payload.sessionId}/start`;
1134
- const finalHeaders = { ...headers || {} };
1135
- if (!Object.keys(finalHeaders).some((key) => key.toLowerCase() === "content-type")) {
1136
- finalHeaders["content-type"] = "application/json";
1150
+ const statusLine = `HTTP ${response.status}${response.statusText ? ` ${response.statusText}` : ""}`;
1151
+ const bodyPreview = responseText ? ` - ${responseText.slice(0, 200)}` : "";
1152
+ const message = `${statusLine}${bodyPreview}`;
1153
+ if (TRACE_HTTP_RETRYABLE_STATUS.has(response.status)) {
1154
+ throw new RetryableHttpError(response.status, message, parseRetryAfterMs(response.headers.get("retry-after")));
1137
1155
  }
1138
- try {
1139
- const response = await fetchFn(url, {
1140
- method: "POST",
1141
- headers: finalHeaders,
1142
- body: JSON.stringify(payload)
1143
- });
1144
- if (!response.ok) {
1145
- let responseText = "";
1146
- try {
1147
- responseText = await response.text();
1148
- } catch {
1156
+ throw new Error(message);
1157
+ }
1158
+ async function postJsonReliable(url, headers, body, opts = {}) {
1159
+ const maxAttempts = opts.retry === false ? 1 : TRACE_HTTP_MAX_ATTEMPTS;
1160
+ let lastError;
1161
+ for (let attempt = 1; attempt <= maxAttempts; attempt += 1) {
1162
+ try {
1163
+ await postJsonOnce(url, headers, body);
1164
+ return;
1165
+ } catch (err) {
1166
+ lastError = err;
1167
+ if (!(err instanceof RetryableHttpError) || attempt === maxAttempts) {
1168
+ if (typeof console !== "undefined" && typeof console.error === "function") {
1169
+ console.error("[Tracing] Failed to post:", err instanceof Error ? err.message : String(err));
1170
+ }
1171
+ throw err;
1149
1172
  }
1150
- const statusLine = `HTTP ${response.status}${response.statusText ? ` ${response.statusText}` : ""}`;
1151
- const bodyPreview = responseText ? ` - ${responseText.slice(0, 200)}` : "";
1152
- throw new Error(`${statusLine}${bodyPreview}`);
1153
- }
1154
- } catch (err) {
1155
- const errMsg = err instanceof Error ? err.message : String(err);
1156
- if (typeof console !== "undefined" && typeof console.error === "function") {
1157
- console.error("[Tracing] Failed to post session start:", errMsg);
1173
+ const wait = err.retryAfterMs ?? traceBackoffDelay(attempt, TRACE_HTTP_RETRY_BASE_MS, TRACE_HTTP_RETRY_MAX_MS);
1174
+ await traceSleep(Math.min(wait, TRACE_HTTP_RETRY_MAX_MS));
1158
1175
  }
1159
- throw err;
1160
1176
  }
1177
+ throw lastError instanceof Error ? lastError : new Error(String(lastError));
1178
+ }
1179
+ async function postTraceSession(url, headers, payload) {
1180
+ await postJsonReliable(url, headers, payload, { retry: true });
1181
+ }
1182
+ async function postStreamingSessionStart(baseUrl, headers, payload) {
1183
+ const url = `${baseUrl.replace(/\/$/, "")}/stream/${payload.sessionId}/start`;
1184
+ await postJsonReliable(url, headers, payload, { retry: true });
1161
1185
  }
1162
1186
  async function postStreamingEvent(baseUrl, headers, sessionId, event) {
1163
- const fetchFn = typeof globalThis.fetch === "function" ? globalThis.fetch.bind(globalThis) : void 0;
1164
- if (!fetchFn) {
1165
- throw new Error("HTTP sink requires fetch to be available in this runtime.");
1166
- }
1167
1187
  const url = `${baseUrl.replace(/\/$/, "")}/stream/${sessionId}/events`;
1168
- const finalHeaders = { ...headers || {} };
1169
- if (!Object.keys(finalHeaders).some((key) => key.toLowerCase() === "content-type")) {
1170
- finalHeaders["content-type"] = "application/json";
1171
- }
1172
- try {
1173
- const response = await fetchFn(url, {
1174
- method: "POST",
1175
- headers: finalHeaders,
1176
- body: JSON.stringify({ event })
1177
- });
1178
- if (!response.ok) {
1179
- let responseText = "";
1180
- try {
1181
- responseText = await response.text();
1182
- } catch {
1183
- }
1184
- const statusLine = `HTTP ${response.status}${response.statusText ? ` ${response.statusText}` : ""}`;
1185
- const bodyPreview = responseText ? ` - ${responseText.slice(0, 200)}` : "";
1186
- throw new Error(`${statusLine}${bodyPreview}`);
1187
- }
1188
- } catch (err) {
1189
- const errMsg = err instanceof Error ? err.message : String(err);
1190
- if (typeof console !== "undefined" && typeof console.error === "function") {
1191
- console.error("[Tracing] Failed to post streaming event:", errMsg);
1192
- }
1193
- throw err;
1194
- }
1188
+ await postJsonReliable(url, headers, { event }, { retry: false });
1195
1189
  }
1196
1190
  async function postStreamingSessionEnd(baseUrl, headers, payload) {
1197
- const fetchFn = typeof globalThis.fetch === "function" ? globalThis.fetch.bind(globalThis) : void 0;
1198
- if (!fetchFn) {
1199
- throw new Error("HTTP sink requires fetch to be available in this runtime.");
1200
- }
1201
1191
  const url = `${baseUrl.replace(/\/$/, "")}/stream/${payload.sessionId}/end`;
1202
- const finalHeaders = { ...headers || {} };
1203
- if (!Object.keys(finalHeaders).some((key) => key.toLowerCase() === "content-type")) {
1204
- finalHeaders["content-type"] = "application/json";
1205
- }
1206
- try {
1207
- const response = await fetchFn(url, {
1208
- method: "POST",
1209
- headers: finalHeaders,
1210
- body: JSON.stringify(payload)
1211
- });
1212
- if (!response.ok) {
1213
- let responseText = "";
1214
- try {
1215
- responseText = await response.text();
1216
- } catch {
1217
- }
1218
- const statusLine = `HTTP ${response.status}${response.statusText ? ` ${response.statusText}` : ""}`;
1219
- const bodyPreview = responseText ? ` - ${responseText.slice(0, 200)}` : "";
1220
- throw new Error(`${statusLine}${bodyPreview}`);
1221
- }
1222
- } catch (err) {
1223
- const errMsg = err instanceof Error ? err.message : String(err);
1224
- if (typeof console !== "undefined" && typeof console.error === "function") {
1225
- console.error("[Tracing] Failed to post session end:", errMsg);
1226
- }
1227
- throw err;
1228
- }
1192
+ await postJsonReliable(url, headers, payload, { retry: true });
1229
1193
  }
1230
1194
  function isoToUnixNano(iso) {
1231
1195
  const ms = new Date(iso).getTime();
@@ -1598,7 +1562,8 @@ function convertMessageListToSections(messageList) {
1598
1562
  function createTraceSession(opts) {
1599
1563
  const cfg = withDefaults(opts.tracing);
1600
1564
  if (!cfg.enabled) return void 0;
1601
- const sessionId = generateSessionId();
1565
+ const providedSessionId = opts.tracing?.sessionId?.trim();
1566
+ const sessionId = providedSessionId || generateSessionId();
1602
1567
  const traceId = generateTraceId();
1603
1568
  const rootSpanId = generateSpanId();
1604
1569
  const runtime = {
@@ -1606,6 +1571,7 @@ function createTraceSession(opts) {
1606
1571
  traceId,
1607
1572
  rootSpanId,
1608
1573
  threadId: opts.tracing?.threadId,
1574
+ configAgentName: opts.tracing?.agentName?.trim() || void 0,
1609
1575
  startedAt: Date.now(),
1610
1576
  resolvedConfig: cfg,
1611
1577
  events: [],
@@ -1629,11 +1595,12 @@ async function startStreamingSession(session, agentRuntime) {
1629
1595
  if (session.resolvedConfig.mode !== "streaming") return;
1630
1596
  if (session.sessionStarted) return;
1631
1597
  const sink = session.resolvedConfig.sink;
1632
- const agentInfo = agentRuntime ? {
1633
- name: agentRuntime.name || "unknown-agent",
1634
- version: agentRuntime.version,
1635
- model: getModelName(agentRuntime.model) || "unknown-model",
1636
- provider: getProviderName(agentRuntime.model)
1598
+ const resolvedAgentName = session.configAgentName || agentRuntime?.name || "unknown-agent";
1599
+ const agentInfo = agentRuntime || session.configAgentName ? {
1600
+ name: resolvedAgentName,
1601
+ version: agentRuntime?.version,
1602
+ model: getModelName(agentRuntime?.model) || "unknown-model",
1603
+ provider: getProviderName(agentRuntime?.model)
1637
1604
  } : void 0;
1638
1605
  session.agentInfo = agentInfo;
1639
1606
  const configSnapshot = buildConfigSnapshot(session);
@@ -1983,6 +1950,777 @@ function estimatePayloadBytes(value) {
1983
1950
  }
1984
1951
  }
1985
1952
 
1953
+ // src/smart/runtimeConfig.ts
1954
+ var DEFAULT_CRITICAL_TOOLS = ["response", "manage_todo_list", "get_tool_response"];
1955
+ var BASE_DEFAULTS = {
1956
+ limits: { maxToolCalls: 20, maxParallelTools: 5, maxContextTokens: 96e3, maxTotalOutputTokens: 0, maxCostUsd: 0, maxWallClockMs: 0 },
1957
+ summarization: {
1958
+ enable: true,
1959
+ maxTokens: 96e3,
1960
+ summaryTriggerTokens: 72e3,
1961
+ summaryPromptMaxTokens: 12e3,
1962
+ summaryCompressionRatioTarget: 0.45,
1963
+ summaryMode: "incremental",
1964
+ promptTemplate: "",
1965
+ toolFreeCall: true,
1966
+ integrityCheck: true
1967
+ },
1968
+ context: {
1969
+ policy: "hybrid",
1970
+ lastTurnsToKeep: 16,
1971
+ toolResponsePolicy: "summarize_archive",
1972
+ budget: {
1973
+ systemReserveTokens: 2e3,
1974
+ goalsReserveTokens: 2e3,
1975
+ recentTurnsReserveTokens: 18e3,
1976
+ toolResponseReserveTokens: 9e3
1977
+ }
1978
+ },
1979
+ planning: {
1980
+ mode: "off",
1981
+ replanPolicy: "on_failure",
1982
+ everyNSteps: 0
1983
+ },
1984
+ memory: {
1985
+ provider: "inMemory",
1986
+ scope: "session",
1987
+ writePolicy: "auto_important",
1988
+ readPolicy: "hybrid"
1989
+ },
1990
+ delegation: {
1991
+ mode: "role_based",
1992
+ maxDelegationDepth: 2,
1993
+ maxChildCalls: 6,
1994
+ maxParallelChild: 3,
1995
+ childContextPolicy: "scoped",
1996
+ requireJsonOutputContract: true
1997
+ },
1998
+ toolResponses: {
1999
+ maxToolResponseChars: 32e3,
2000
+ maxToolResponseTokens: 8e3,
2001
+ defaultPolicy: "summarize_archive",
2002
+ toolResponseRetentionByTool: {},
2003
+ criticalTools: [...DEFAULT_CRITICAL_TOOLS],
2004
+ schemaValidation: "strict"
2005
+ },
2006
+ contextPilot: {
2007
+ // Opt-in: ContextPilot never alters tool output unless the caller
2008
+ // explicitly passes `contextPilot: { enabled: true }` (or sets `enabled`
2009
+ // via `customProfile`/profile overrides). This preserves backward
2010
+ // compatibility for every existing `createSmartAgent(...)` call site.
2011
+ enabled: false,
2012
+ compression: {
2013
+ json: { enabled: true, targetRatio: 0.35, minItems: 20 },
2014
+ text: { enabled: true, targetRatio: 0.5, minChars: 1200 },
2015
+ diff: { enabled: true, contextLines: 3 },
2016
+ log: { enabled: true, maxLines: 60 },
2017
+ search: { enabled: true, maxMatches: 30 }
2018
+ },
2019
+ ccr: { enabled: true, ttlMs: 30 * 60 * 1e3, maxEntries: 500 },
2020
+ cacheAlignment: { enabled: true, warnOnVolatilePrompt: true },
2021
+ dedup: { enabled: true, minChars: 500 },
2022
+ excludeTools: []
2023
+ }
2024
+ };
2025
+ function mergeContextPilot(base, override) {
2026
+ return {
2027
+ enabled: override?.enabled ?? base.enabled,
2028
+ compression: {
2029
+ json: { ...base.compression.json, ...override?.compression?.json },
2030
+ text: { ...base.compression.text, ...override?.compression?.text },
2031
+ diff: { ...base.compression.diff, ...override?.compression?.diff },
2032
+ log: { ...base.compression.log, ...override?.compression?.log },
2033
+ search: { ...base.compression.search, ...override?.compression?.search }
2034
+ },
2035
+ ccr: { ...base.ccr, ...override?.ccr },
2036
+ cacheAlignment: { ...base.cacheAlignment, ...override?.cacheAlignment },
2037
+ dedup: { ...base.dedup, ...override?.dedup },
2038
+ excludeTools: override?.excludeTools ?? base.excludeTools
2039
+ };
2040
+ }
2041
+ function buildProfile(overrides) {
2042
+ return {
2043
+ limits: { ...BASE_DEFAULTS.limits, ...overrides.limits },
2044
+ summarization: { ...BASE_DEFAULTS.summarization, ...overrides.summarization },
2045
+ context: {
2046
+ ...BASE_DEFAULTS.context,
2047
+ ...overrides.context,
2048
+ budget: { ...BASE_DEFAULTS.context.budget, ...overrides.context?.budget }
2049
+ },
2050
+ planning: { ...BASE_DEFAULTS.planning, ...overrides.planning },
2051
+ memory: { ...BASE_DEFAULTS.memory, ...overrides.memory },
2052
+ delegation: { ...BASE_DEFAULTS.delegation, ...overrides.delegation },
2053
+ toolResponses: {
2054
+ ...BASE_DEFAULTS.toolResponses,
2055
+ ...overrides.toolResponses,
2056
+ criticalTools: overrides.toolResponses?.criticalTools ?? [...DEFAULT_CRITICAL_TOOLS],
2057
+ toolResponseRetentionByTool: overrides.toolResponses?.toolResponseRetentionByTool ?? {}
2058
+ },
2059
+ contextPilot: mergeContextPilot(BASE_DEFAULTS.contextPilot, overrides.contextPilot)
2060
+ };
2061
+ }
2062
+ var DEFAULT_PROFILE_CONFIGS = {
2063
+ fast: buildProfile({
2064
+ limits: { maxToolCalls: 8, maxParallelTools: 3, maxContextTokens: 32e3 },
2065
+ summarization: {
2066
+ maxTokens: 32e3,
2067
+ summaryTriggerTokens: 24e3,
2068
+ summaryPromptMaxTokens: 6e3,
2069
+ summaryCompressionRatioTarget: 0.5
2070
+ },
2071
+ context: {
2072
+ lastTurnsToKeep: 8,
2073
+ toolResponsePolicy: "keep_structured",
2074
+ budget: { systemReserveTokens: 1500, goalsReserveTokens: 1200, recentTurnsReserveTokens: 6e3, toolResponseReserveTokens: 3500 }
2075
+ },
2076
+ memory: { readPolicy: "recent_only" },
2077
+ delegation: { mode: "off", maxDelegationDepth: 1, maxChildCalls: 2, maxParallelChild: 1, childContextPolicy: "minimal" },
2078
+ toolResponses: { maxToolResponseChars: 16e3, maxToolResponseTokens: 4e3 },
2079
+ contextPilot: {
2080
+ compression: {
2081
+ json: { targetRatio: 0.25, minItems: 12 },
2082
+ text: { targetRatio: 0.35, minChars: 800 }
2083
+ }
2084
+ }
2085
+ }),
2086
+ balanced: buildProfile({}),
2087
+ deep: buildProfile({
2088
+ limits: { maxToolCalls: 40, maxParallelTools: 8, maxContextTokens: 2e5 },
2089
+ summarization: {
2090
+ maxTokens: 2e5,
2091
+ summaryTriggerTokens: 15e4,
2092
+ summaryPromptMaxTokens: 16e3,
2093
+ summaryCompressionRatioTarget: 0.4
2094
+ },
2095
+ context: {
2096
+ lastTurnsToKeep: 30,
2097
+ budget: { systemReserveTokens: 2500, goalsReserveTokens: 2500, recentTurnsReserveTokens: 36e3, toolResponseReserveTokens: 18e3 }
2098
+ },
2099
+ memory: { scope: "workspace" },
2100
+ delegation: { maxDelegationDepth: 3, maxChildCalls: 10, maxParallelChild: 4 },
2101
+ toolResponses: { maxToolResponseChars: 64e3, maxToolResponseTokens: 16e3 },
2102
+ contextPilot: {
2103
+ compression: {
2104
+ json: { targetRatio: 0.5, minItems: 30 },
2105
+ text: { targetRatio: 0.6, minChars: 1600 }
2106
+ },
2107
+ ccr: { ttlMs: 60 * 60 * 1e3 }
2108
+ }
2109
+ }),
2110
+ research: buildProfile({
2111
+ limits: { maxToolCalls: 80, maxParallelTools: 10, maxContextTokens: 4e5 },
2112
+ summarization: {
2113
+ maxTokens: 4e5,
2114
+ summaryTriggerTokens: 3e5,
2115
+ summaryPromptMaxTokens: 24e3,
2116
+ summaryCompressionRatioTarget: 0.35
2117
+ },
2118
+ context: {
2119
+ lastTurnsToKeep: 60,
2120
+ budget: { systemReserveTokens: 3e3, goalsReserveTokens: 3e3, recentTurnsReserveTokens: 72e3, toolResponseReserveTokens: 32e3 }
2121
+ },
2122
+ memory: { scope: "workspace" },
2123
+ delegation: { mode: "automatic", maxDelegationDepth: 4, maxChildCalls: 16, maxParallelChild: 6, childContextPolicy: "full" },
2124
+ toolResponses: { maxToolResponseChars: 96e3, maxToolResponseTokens: 24e3 },
2125
+ contextPilot: {
2126
+ compression: {
2127
+ json: { targetRatio: 0.6, minItems: 40 },
2128
+ text: { targetRatio: 0.65, minChars: 2e3 }
2129
+ },
2130
+ ccr: { ttlMs: 2 * 60 * 60 * 1e3, maxEntries: 1e3 }
2131
+ }
2132
+ })
2133
+ };
2134
+ function mergeLimits(base, override) {
2135
+ return {
2136
+ maxToolCalls: override?.maxToolCalls ?? base.maxToolCalls,
2137
+ maxParallelTools: override?.maxParallelTools ?? base.maxParallelTools,
2138
+ maxContextTokens: override?.maxContextTokens ?? base.maxContextTokens,
2139
+ maxTotalOutputTokens: override?.maxTotalOutputTokens ?? base.maxTotalOutputTokens ?? 0,
2140
+ maxCostUsd: override?.maxCostUsd ?? base.maxCostUsd ?? 0,
2141
+ maxWallClockMs: override?.maxWallClockMs ?? base.maxWallClockMs ?? 0
2142
+ };
2143
+ }
2144
+ function resolveBaseProfile(opts, runtimeProfile) {
2145
+ if (opts.customProfile?.extends) return opts.customProfile.extends;
2146
+ if (runtimeProfile !== "custom") return runtimeProfile;
2147
+ return "balanced";
2148
+ }
2149
+ function normalizeSmartAgentOptions(opts) {
2150
+ const runtimeProfile = opts.runtimeProfile ?? (opts.customProfile ? "custom" : "balanced");
2151
+ const baseProfile = resolveBaseProfile(opts, runtimeProfile);
2152
+ const preset = DEFAULT_PROFILE_CONFIGS[baseProfile];
2153
+ const customProfile = opts.customProfile || {};
2154
+ const useTodoList = opts.useTodoList === true;
2155
+ const summarizationDisabled = opts.summarization === false;
2156
+ const summarizationOverride = typeof opts.summarization === "object" ? opts.summarization : {};
2157
+ const planningMode = opts.planning?.mode ?? customProfile.planning?.mode ?? (useTodoList ? "todo" : preset.planning.mode);
2158
+ const memoryStore = opts.memory?.store ?? customProfile.memory?.store;
2159
+ const contextToolResponsePolicy = opts.context?.toolResponsePolicy ?? customProfile.context?.toolResponsePolicy ?? preset.context.toolResponsePolicy;
2160
+ return {
2161
+ runtimeProfile,
2162
+ baseProfile,
2163
+ limits: mergeLimits(mergeLimits(preset.limits, customProfile.limits), opts.limits),
2164
+ summarization: {
2165
+ ...preset.summarization,
2166
+ ...customProfile.summarization || {},
2167
+ ...summarizationOverride,
2168
+ enable: summarizationDisabled ? false : summarizationOverride.enable ?? customProfile.summarization?.enable ?? preset.summarization.enable,
2169
+ maxTokens: summarizationOverride.maxTokens ?? opts.limits?.maxContextTokens ?? customProfile.summarization?.maxTokens ?? preset.summarization.maxTokens,
2170
+ summaryTriggerTokens: summarizationOverride.summaryTriggerTokens ?? summarizationOverride.maxTokens ?? opts.limits?.maxContextTokens ?? customProfile.summarization?.summaryTriggerTokens ?? customProfile.summarization?.maxTokens ?? preset.summarization.summaryTriggerTokens,
2171
+ promptTemplate: summarizationOverride.promptTemplate ?? customProfile.summarization?.promptTemplate ?? preset.summarization.promptTemplate
2172
+ },
2173
+ context: {
2174
+ ...preset.context,
2175
+ ...customProfile.context || {},
2176
+ ...opts.context || {},
2177
+ budget: {
2178
+ ...preset.context.budget,
2179
+ ...customProfile.context?.budget || {},
2180
+ ...opts.context?.budget || {}
2181
+ },
2182
+ toolResponsePolicy: contextToolResponsePolicy
2183
+ },
2184
+ planning: {
2185
+ ...preset.planning,
2186
+ ...customProfile.planning || {},
2187
+ ...opts.planning || {},
2188
+ mode: planningMode
2189
+ },
2190
+ memory: {
2191
+ ...preset.memory,
2192
+ ...customProfile.memory || {},
2193
+ ...opts.memory || {},
2194
+ store: memoryStore
2195
+ },
2196
+ delegation: {
2197
+ ...preset.delegation,
2198
+ ...customProfile.delegation || {},
2199
+ ...opts.delegation || {}
2200
+ },
2201
+ toolResponses: {
2202
+ ...preset.toolResponses,
2203
+ ...customProfile.toolResponses || {},
2204
+ ...opts.toolResponses || {},
2205
+ defaultPolicy: opts.toolResponses?.defaultPolicy ?? customProfile.toolResponses?.defaultPolicy ?? contextToolResponsePolicy,
2206
+ toolResponseRetentionByTool: {
2207
+ ...preset.toolResponses.toolResponseRetentionByTool,
2208
+ ...customProfile.toolResponses?.toolResponseRetentionByTool || {},
2209
+ ...opts.toolResponses?.toolResponseRetentionByTool || {}
2210
+ },
2211
+ criticalTools: opts.toolResponses?.criticalTools ?? customProfile.toolResponses?.criticalTools ?? preset.toolResponses.criticalTools
2212
+ },
2213
+ contextPilot: mergeContextPilot(mergeContextPilot(preset.contextPilot, customProfile.contextPilot), opts.contextPilot)
2214
+ };
2215
+ }
2216
+ function getResolvedSmartConfig(opts, runtime) {
2217
+ return runtime?.smart || normalizeSmartAgentOptions(opts);
2218
+ }
2219
+
2220
+ // src/smart/contextPilot/relevance.ts
2221
+ var STOPWORDS = /* @__PURE__ */ new Set([
2222
+ "the",
2223
+ "a",
2224
+ "an",
2225
+ "and",
2226
+ "or",
2227
+ "but",
2228
+ "if",
2229
+ "then",
2230
+ "else",
2231
+ "for",
2232
+ "of",
2233
+ "in",
2234
+ "on",
2235
+ "at",
2236
+ "to",
2237
+ "by",
2238
+ "with",
2239
+ "is",
2240
+ "are",
2241
+ "was",
2242
+ "were",
2243
+ "be",
2244
+ "been",
2245
+ "being",
2246
+ "this",
2247
+ "that",
2248
+ "these",
2249
+ "those",
2250
+ "it",
2251
+ "its",
2252
+ "as",
2253
+ "from"
2254
+ ]);
2255
+ function tokenize(text) {
2256
+ if (!text) return [];
2257
+ const matches = text.toLowerCase().match(/[\p{L}\p{N}_]+/gu);
2258
+ if (!matches) return [];
2259
+ return matches.filter((token) => token.length > 1 && !STOPWORDS.has(token));
2260
+ }
2261
+ function scoreItemsByRelevance(docs, query, params = {}) {
2262
+ const k1 = params.k1 ?? 1.5;
2263
+ const b = params.b ?? 0.75;
2264
+ const queryTokens = tokenize(query);
2265
+ const docTokens = docs.map((doc) => tokenize(doc));
2266
+ if (queryTokens.length === 0) {
2267
+ return docs.map(() => 1);
2268
+ }
2269
+ const docLengths = docTokens.map((tokens) => tokens.length);
2270
+ const avgDocLen = docLengths.reduce((sum2, len) => sum2 + len, 0) / Math.max(1, docLengths.length);
2271
+ const uniqueQueryTerms = [...new Set(queryTokens)];
2272
+ const df = /* @__PURE__ */ new Map();
2273
+ for (const term of uniqueQueryTerms) {
2274
+ let count = 0;
2275
+ for (const tokens of docTokens) {
2276
+ if (tokens.includes(term)) count += 1;
2277
+ }
2278
+ df.set(term, count);
2279
+ }
2280
+ const n = docs.length;
2281
+ const idf = /* @__PURE__ */ new Map();
2282
+ for (const term of uniqueQueryTerms) {
2283
+ const freq = df.get(term) || 0;
2284
+ idf.set(term, Math.log(1 + (n - freq + 0.5) / (freq + 0.5)));
2285
+ }
2286
+ return docTokens.map((tokens, docIndex) => {
2287
+ if (tokens.length === 0) return 0;
2288
+ const termFreq = /* @__PURE__ */ new Map();
2289
+ for (const token of tokens) {
2290
+ termFreq.set(token, (termFreq.get(token) || 0) + 1);
2291
+ }
2292
+ const docLen = docLengths[docIndex];
2293
+ let score = 0;
2294
+ for (const term of uniqueQueryTerms) {
2295
+ const freq = termFreq.get(term) || 0;
2296
+ if (freq === 0) continue;
2297
+ const termIdf = idf.get(term) || 0;
2298
+ const numerator = freq * (k1 + 1);
2299
+ const denominator = freq + k1 * (1 - b + b * docLen / avgDocLen);
2300
+ score += termIdf * (numerator / denominator);
2301
+ }
2302
+ return score;
2303
+ });
2304
+ }
2305
+ function selectTopIndicesInOrder(scores, count) {
2306
+ const ranked = scores.map((score, index) => ({ score, index })).sort((a, b) => b.score - a.score).slice(0, Math.max(0, count)).map((entry) => entry.index);
2307
+ return ranked.sort((a, b) => a - b);
2308
+ }
2309
+ var CCRStore = class _CCRStore {
2310
+ constructor(options = {}) {
2311
+ this.entries = /* @__PURE__ */ new Map();
2312
+ this.defaultTtlMs = options.ttlMs ?? 30 * 60 * 1e3;
2313
+ this.maxEntries = options.maxEntries ?? 500;
2314
+ }
2315
+ /** Stores `value` and returns a short content hash that can be used to retrieve it later. */
2316
+ store(value, ttlMs) {
2317
+ const hash = _CCRStore.hashOf(value);
2318
+ this.entries.delete(hash);
2319
+ this.entries.set(hash, { value, storedAt: Date.now(), ttlMs: ttlMs ?? this.defaultTtlMs });
2320
+ this.evictIfNeeded();
2321
+ return hash;
2322
+ }
2323
+ /** Returns the original value for `hash`, or `undefined` if missing/expired. */
2324
+ retrieve(hash) {
2325
+ const entry = this.entries.get(hash);
2326
+ if (!entry) return void 0;
2327
+ if (Date.now() - entry.storedAt > entry.ttlMs) {
2328
+ this.entries.delete(hash);
2329
+ return void 0;
2330
+ }
2331
+ return entry.value;
2332
+ }
2333
+ has(hash) {
2334
+ return this.retrieve(hash) !== void 0;
2335
+ }
2336
+ get size() {
2337
+ return this.entries.size;
2338
+ }
2339
+ evictIfNeeded() {
2340
+ while (this.entries.size > this.maxEntries) {
2341
+ const oldestKey = this.entries.keys().next().value;
2342
+ if (oldestKey === void 0) break;
2343
+ this.entries.delete(oldestKey);
2344
+ }
2345
+ }
2346
+ static hashOf(value) {
2347
+ const serialized = typeof value === "string" ? value : JSON.stringify(value);
2348
+ return crypto.createHash("sha1").update(serialized).digest("hex").slice(0, 16);
2349
+ }
2350
+ };
2351
+ var DedupTracker = class {
2352
+ constructor() {
2353
+ this.seen = /* @__PURE__ */ new Map();
2354
+ }
2355
+ /**
2356
+ * Registers `content` under `executionId`/`toolName`. Returns the entry
2357
+ * that first produced this exact content, or `undefined` if this is the
2358
+ * first time it has been seen.
2359
+ */
2360
+ checkAndRegister(content, executionId, toolName) {
2361
+ const hash = crypto.createHash("sha1").update(content).digest("hex");
2362
+ const existing = this.seen.get(hash);
2363
+ if (!existing) {
2364
+ this.seen.set(hash, { executionId, toolName });
2365
+ }
2366
+ return existing;
2367
+ }
2368
+ };
2369
+
2370
+ // src/smart/contextPilot/cacheAligner.ts
2371
+ var PATTERNS = [
2372
+ { kind: "uuid", regex: /\b[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}\b/g },
2373
+ { kind: "iso8601", regex: /\b\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d+)?(?:Z|[+-]\d{2}:?\d{2})?\b/g },
2374
+ { kind: "jwt", regex: /\beyJ[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\b/g },
2375
+ { kind: "hex_hash", regex: /\b[0-9a-fA-F]{64}\b|\b[0-9a-fA-F]{40}\b|\b[0-9a-fA-F]{32}\b/g },
2376
+ { kind: "api_key", regex: /\b(?:sk|pk|ghp|gho|ghu|ghs)-[A-Za-z0-9]{10,}\b/g },
2377
+ { kind: "unix_timestamp", regex: /\b1\d{12}\b(?!\d)|\b1\d{9}\b(?!\d)/g }
2378
+ ];
2379
+ function detectVolatileContent(text, limit = 20) {
2380
+ if (!text) return [];
2381
+ const findings = [];
2382
+ for (const { kind, regex } of PATTERNS) {
2383
+ regex.lastIndex = 0;
2384
+ let match;
2385
+ while (findings.length < limit && (match = regex.exec(text)) !== null) {
2386
+ findings.push({ pattern: kind, match: match[0], index: match.index });
2387
+ if (regex.lastIndex === match.index) regex.lastIndex += 1;
2388
+ }
2389
+ }
2390
+ return findings;
2391
+ }
2392
+
2393
+ // src/smart/contextPilot/jsonCrusher.ts
2394
+ init_utilTokens();
2395
+
2396
+ // src/utils/content.ts
2397
+ function contentToString(content) {
2398
+ try {
2399
+ if (content == null) return "";
2400
+ if (typeof content === "string") return content;
2401
+ if (Array.isArray(content)) {
2402
+ return content.map((p) => {
2403
+ if (!p || typeof p !== "object") return String(p);
2404
+ if (p.type === "text") return String(p.text ?? "");
2405
+ if (p.type === "image_url") {
2406
+ const img = p.image_url;
2407
+ const url = typeof img === "string" ? img : img?.url;
2408
+ const detail = typeof img === "string" ? void 0 : img?.detail;
2409
+ return `[image:${url || "unknown"}${detail ? ` detail=${detail}` : ""}]`;
2410
+ }
2411
+ return JSON.stringify(p);
2412
+ }).join("\n");
2413
+ }
2414
+ return JSON.stringify(content);
2415
+ } catch {
2416
+ return String(content);
2417
+ }
2418
+ }
2419
+ function mergeContentsToString(contents) {
2420
+ return contents.map((c) => contentToString(c)).join("\n");
2421
+ }
2422
+ function safeStringify(value, pretty = false) {
2423
+ if (value == null) return "";
2424
+ if (typeof value === "string") return value;
2425
+ try {
2426
+ return JSON.stringify(value, null, pretty ? 2 : void 0) ?? String(value);
2427
+ } catch {
2428
+ return String(value);
2429
+ }
2430
+ }
2431
+ function extractMessageText2(message) {
2432
+ if (!message) return "";
2433
+ const content = message.content;
2434
+ if (typeof content === "string") return content;
2435
+ if (Array.isArray(content)) {
2436
+ return content.map((part) => typeof part === "string" ? part : part?.text ?? part?.content ?? "").join("");
2437
+ }
2438
+ return "";
2439
+ }
2440
+
2441
+ // src/smart/contextPilot/jsonCrusher.ts
2442
+ var CONTEXT_PILOT_JSON_MARKER_KEY = "__contextPilotDropped";
2443
+ function findCompressibleArray(output, minItems) {
2444
+ if (Array.isArray(output)) {
2445
+ return { array: output, wrap: (arr) => arr };
2446
+ }
2447
+ if (output && typeof output === "object") {
2448
+ let bestKey;
2449
+ let bestArray;
2450
+ for (const [key, value] of Object.entries(output)) {
2451
+ if (Array.isArray(value) && (!bestArray || value.length > bestArray.length)) {
2452
+ bestKey = key;
2453
+ bestArray = value;
2454
+ }
2455
+ }
2456
+ if (bestKey && bestArray && bestArray.length >= minItems) {
2457
+ const key = bestKey;
2458
+ return {
2459
+ array: bestArray,
2460
+ wrap: (arr) => ({ ...output, [key]: arr })
2461
+ };
2462
+ }
2463
+ }
2464
+ return null;
2465
+ }
2466
+ function notApplied(output) {
2467
+ const tokens = countApproxTokens(safeStringify(output));
2468
+ return { applied: false, compressorUsed: "none", output, originalTokens: tokens, compressedTokens: tokens };
2469
+ }
2470
+ function compressJsonOutput(output, query, config, ccrStore) {
2471
+ if (!config.enabled) return notApplied(output);
2472
+ const target = findCompressibleArray(output, config.minItems);
2473
+ if (!target || target.array.length < config.minItems) return notApplied(output);
2474
+ const { array, wrap } = target;
2475
+ const itemTexts = array.map((item) => safeStringify(item));
2476
+ const scores = scoreItemsByRelevance(itemTexts, query);
2477
+ const keepCount = Math.max(1, Math.min(array.length, Math.ceil(array.length * config.targetRatio)));
2478
+ const keepIndices = new Set(selectTopIndicesInOrder(scores, keepCount));
2479
+ const droppedCount = array.length - keepIndices.size;
2480
+ if (droppedCount <= 0) return notApplied(output);
2481
+ const originalTokens = countApproxTokens(safeStringify(output));
2482
+ const ccrHash = ccrStore.store(output);
2483
+ const keptItems = array.filter((_item, index) => keepIndices.has(index));
2484
+ const marker = {
2485
+ [CONTEXT_PILOT_JSON_MARKER_KEY]: droppedCount,
2486
+ note: `${droppedCount} lower-relevance item(s) omitted by ContextPilot. Use get_tool_response with executionId="${ccrHash}" to retrieve the full original array if a dropped item is actually needed.`
2487
+ };
2488
+ const compressedOutput = wrap([...keptItems, marker]);
2489
+ const compressedTokens = countApproxTokens(safeStringify(compressedOutput));
2490
+ if (compressedTokens >= originalTokens * 0.9) return notApplied(output);
2491
+ return {
2492
+ applied: true,
2493
+ compressorUsed: "jsonCrusher",
2494
+ output: compressedOutput,
2495
+ originalTokens,
2496
+ compressedTokens,
2497
+ droppedItems: droppedCount,
2498
+ ccrHash
2499
+ };
2500
+ }
2501
+
2502
+ // src/smart/contextPilot/textCrusher.ts
2503
+ init_utilTokens();
2504
+ function splitIntoSentences(text) {
2505
+ return text.split(/(?<=[.!?。!?\n])\s*/u).map((sentence) => sentence.trim()).filter(Boolean);
2506
+ }
2507
+ function normalizeForDedup(sentence) {
2508
+ return sentence.toLowerCase().replace(/\s+/g, " ").trim();
2509
+ }
2510
+ function notApplied2(text) {
2511
+ const tokens = countApproxTokens(text);
2512
+ return { applied: false, compressorUsed: "none", output: text, originalTokens: tokens, compressedTokens: tokens };
2513
+ }
2514
+ function compressTextOutput(text, query, config, ccrStore) {
2515
+ if (!config.enabled || text.length < config.minChars) return notApplied2(text);
2516
+ const rawSentences = splitIntoSentences(text);
2517
+ if (rawSentences.length < 6) return notApplied2(text);
2518
+ const seenNormalized = /* @__PURE__ */ new Set();
2519
+ const dedupedIndices = [];
2520
+ rawSentences.forEach((sentence, index) => {
2521
+ const key = normalizeForDedup(sentence);
2522
+ if (seenNormalized.has(key)) return;
2523
+ seenNormalized.add(key);
2524
+ dedupedIndices.push(index);
2525
+ });
2526
+ const relevanceScores = scoreItemsByRelevance(dedupedIndices.map((i) => rawSentences[i]), query);
2527
+ const recencyBoost = dedupedIndices.map((_value, position) => position / Math.max(1, dedupedIndices.length - 1));
2528
+ const combinedScores = relevanceScores.map((score, i) => score + recencyBoost[i] * 0.25);
2529
+ const keepCount = Math.max(3, Math.ceil(dedupedIndices.length * config.targetRatio));
2530
+ const keepPositions = new Set(selectTopIndicesInOrder(combinedScores, keepCount));
2531
+ const keptSentences = dedupedIndices.filter((_index, position) => keepPositions.has(position)).map((i) => rawSentences[i]);
2532
+ const droppedCount = rawSentences.length - keptSentences.length;
2533
+ if (droppedCount <= 0) return notApplied2(text);
2534
+ const originalTokens = countApproxTokens(text);
2535
+ const ccrHash = ccrStore.store(text);
2536
+ const compressedText = `${keptSentences.join(" ")}
2537
+ [ContextPilot: ${droppedCount} lower-relevance sentence(s) omitted. Use get_tool_response with executionId="${ccrHash}" to retrieve the full original text.]`;
2538
+ const compressedTokens = countApproxTokens(compressedText);
2539
+ if (compressedTokens >= originalTokens * 0.9) return notApplied2(text);
2540
+ return {
2541
+ applied: true,
2542
+ compressorUsed: "textCrusher",
2543
+ output: compressedText,
2544
+ originalTokens,
2545
+ compressedTokens,
2546
+ droppedItems: droppedCount,
2547
+ ccrHash
2548
+ };
2549
+ }
2550
+
2551
+ // src/smart/contextPilot/formatCompressors.ts
2552
+ init_utilTokens();
2553
+ function notApplied3(text) {
2554
+ const tokens = countApproxTokens(text);
2555
+ return { applied: false, compressorUsed: "none", output: text, originalTokens: tokens, compressedTokens: tokens };
2556
+ }
2557
+ function detectTextFormat(text) {
2558
+ const sample = text.slice(0, 2e3);
2559
+ if (/^diff --git |^---\s|^\+\+\+\s|^@@ -\d+/m.test(sample)) return "diff";
2560
+ if (/^[\w./-]+:\d+:/m.test(sample) || /^[\w./-]+-\d+-/m.test(sample)) return "search";
2561
+ if (/\b(ERROR|FAIL|FAILED|WARN|PASS|PASSED)\b/.test(sample) && text.split("\n").length > 15) return "log";
2562
+ return "text";
2563
+ }
2564
+ function compressDiffOutput(text, config, ccrStore) {
2565
+ if (!config.enabled) return notApplied3(text);
2566
+ const lines = text.split("\n");
2567
+ const kept = [];
2568
+ let contextRun = 0;
2569
+ let trimmedAny = false;
2570
+ for (const line of lines) {
2571
+ const isHeader = line.startsWith("diff --git") || line.startsWith("---") || line.startsWith("+++") || line.startsWith("@@");
2572
+ const isChange = line.startsWith("+") || line.startsWith("-");
2573
+ if (isHeader || isChange) {
2574
+ kept.push(line);
2575
+ contextRun = 0;
2576
+ continue;
2577
+ }
2578
+ if (contextRun < config.contextLines) {
2579
+ kept.push(line);
2580
+ contextRun += 1;
2581
+ } else {
2582
+ trimmedAny = true;
2583
+ }
2584
+ }
2585
+ if (!trimmedAny) return notApplied3(text);
2586
+ const originalTokens = countApproxTokens(text);
2587
+ const ccrHash = ccrStore.store(text);
2588
+ const compressedText = `${kept.join("\n")}
2589
+ [ContextPilot: unchanged context lines beyond ${config.contextLines} trimmed. Use get_tool_response with executionId="${ccrHash}" to retrieve the full diff.]`;
2590
+ const compressedTokens = countApproxTokens(compressedText);
2591
+ if (compressedTokens >= originalTokens * 0.9) return notApplied3(text);
2592
+ return { applied: true, compressorUsed: "diffCompressor", output: compressedText, originalTokens, compressedTokens, ccrHash };
2593
+ }
2594
+ var LOG_LEVEL_SCORE = [
2595
+ { regex: /\b(FAIL|FAILED|ERROR|FATAL|EXCEPTION|TRACEBACK)\b/i, score: 1 },
2596
+ { regex: /\b(WARN|WARNING)\b/i, score: 0.7 },
2597
+ { regex: /\b(PASS|PASSED|OK|SUCCESS)\b/i, score: 0.4 },
2598
+ { regex: /\bINFO\b/i, score: 0.3 },
2599
+ { regex: /\b(DEBUG|TRACE)\b/i, score: 0.1 }
2600
+ ];
2601
+ function scoreLogLine(line) {
2602
+ for (const { regex, score } of LOG_LEVEL_SCORE) {
2603
+ if (regex.test(line)) return score;
2604
+ }
2605
+ return 0.2;
2606
+ }
2607
+ function compressLogOutput(text, config, ccrStore) {
2608
+ if (!config.enabled) return notApplied3(text);
2609
+ const lines = text.split("\n").filter((line) => line.length > 0);
2610
+ if (lines.length <= config.maxLines) return notApplied3(text);
2611
+ const scored = lines.map((line, index) => ({ line, index, score: scoreLogLine(line) }));
2612
+ const mustKeep = /* @__PURE__ */ new Set([0, lines.length - 1]);
2613
+ const ranked = scored.filter((entry) => !mustKeep.has(entry.index)).sort((a, b) => b.score - a.score).slice(0, Math.max(0, config.maxLines - mustKeep.size)).map((entry) => entry.index);
2614
+ const keepIndices = /* @__PURE__ */ new Set([...mustKeep, ...ranked]);
2615
+ const droppedCount = lines.length - keepIndices.size;
2616
+ if (droppedCount <= 0) return notApplied3(text);
2617
+ const originalTokens = countApproxTokens(text);
2618
+ const ccrHash = ccrStore.store(text);
2619
+ const keptLines = lines.filter((_line, index) => keepIndices.has(index));
2620
+ const compressedText = `${keptLines.join("\n")}
2621
+ [ContextPilot: ${droppedCount} lower-priority log line(s) omitted (errors/warnings preserved). Use get_tool_response with executionId="${ccrHash}" to retrieve the full log.]`;
2622
+ const compressedTokens = countApproxTokens(compressedText);
2623
+ if (compressedTokens >= originalTokens * 0.9) return notApplied3(text);
2624
+ return { applied: true, compressorUsed: "logCompressor", output: compressedText, originalTokens, compressedTokens, droppedItems: droppedCount, ccrHash };
2625
+ }
2626
+ function compressSearchOutput(text, config, ccrStore) {
2627
+ if (!config.enabled) return notApplied3(text);
2628
+ const lines = text.split("\n").filter((line) => line.length > 0);
2629
+ if (lines.length <= config.maxMatches) return notApplied3(text);
2630
+ const perFileCount = /* @__PURE__ */ new Map();
2631
+ const perFileCap = Math.max(3, Math.ceil(config.maxMatches / 4));
2632
+ const kept = [];
2633
+ for (const line of lines) {
2634
+ if (kept.length >= config.maxMatches) break;
2635
+ const fileKey = line.split(/[:-]/)[0] || "unknown";
2636
+ const count = perFileCount.get(fileKey) || 0;
2637
+ if (count >= perFileCap) continue;
2638
+ perFileCount.set(fileKey, count + 1);
2639
+ kept.push(line);
2640
+ }
2641
+ const droppedCount = lines.length - kept.length;
2642
+ if (droppedCount <= 0) return notApplied3(text);
2643
+ const originalTokens = countApproxTokens(text);
2644
+ const ccrHash = ccrStore.store(text);
2645
+ const compressedText = `${kept.join("\n")}
2646
+ [ContextPilot: ${droppedCount} additional match(es) omitted. Use get_tool_response with executionId="${ccrHash}" to retrieve all matches.]`;
2647
+ const compressedTokens = countApproxTokens(compressedText);
2648
+ if (compressedTokens >= originalTokens * 0.9) return notApplied3(text);
2649
+ return { applied: true, compressorUsed: "searchCompressor", output: compressedText, originalTokens, compressedTokens, droppedItems: droppedCount, ccrHash };
2650
+ }
2651
+
2652
+ // src/smart/contextPilot/pipeline.ts
2653
+ init_utilTokens();
2654
+ function createContextPilotRuntime(config) {
2655
+ return {
2656
+ ccrStore: new CCRStore({ ttlMs: config.ccr.ttlMs, maxEntries: config.ccr.maxEntries }),
2657
+ dedupTracker: new DedupTracker()
2658
+ };
2659
+ }
2660
+ function extractLatestUserQuery(messages) {
2661
+ if (!Array.isArray(messages)) return "";
2662
+ for (let i = messages.length - 1; i >= 0; i -= 1) {
2663
+ const message = messages[i];
2664
+ if (message?.role !== "user") continue;
2665
+ if (typeof message.content === "string") return message.content;
2666
+ if (Array.isArray(message.content)) {
2667
+ return message.content.map((part) => typeof part?.text === "string" ? part.text : "").filter(Boolean).join(" ");
2668
+ }
2669
+ }
2670
+ return "";
2671
+ }
2672
+ function notApplied4(output) {
2673
+ const tokens = countApproxTokens(safeStringify(output));
2674
+ return { applied: false, compressorUsed: "none", output, originalTokens: tokens, compressedTokens: tokens };
2675
+ }
2676
+ function compressToolOutput(params) {
2677
+ const { toolName, output, query, executionId, config, runtime } = params;
2678
+ if (!config.enabled || config.excludeTools.includes(toolName)) return notApplied4(output);
2679
+ const ccrAvailable = config.ccr.enabled && config.ccr.maxEntries > 0;
2680
+ if (config.dedup.enabled) {
2681
+ const serialized = typeof output === "string" ? output : safeStringify(output);
2682
+ if (serialized.length >= config.dedup.minChars) {
2683
+ const duplicate = runtime.dedupTracker.checkAndRegister(serialized, executionId, toolName);
2684
+ if (duplicate) {
2685
+ const originalTokens = countApproxTokens(serialized);
2686
+ const pointer = `DUPLICATE_TOOL_RESPONSE [toolName=${toolName}]
2687
+ Identical to an earlier ${duplicate.toolName} result. Use get_tool_response with executionId="${duplicate.executionId}" to view it.`;
2688
+ return {
2689
+ applied: true,
2690
+ compressorUsed: "none",
2691
+ output: pointer,
2692
+ originalTokens,
2693
+ compressedTokens: countApproxTokens(pointer),
2694
+ duplicateOf: duplicate.executionId
2695
+ };
2696
+ }
2697
+ }
2698
+ }
2699
+ if (typeof output !== "string") {
2700
+ if (ccrAvailable && config.compression.json.enabled) {
2701
+ const result = compressJsonOutput(output, query, config.compression.json, runtime.ccrStore);
2702
+ if (result.applied) return result;
2703
+ }
2704
+ return notApplied4(output);
2705
+ }
2706
+ const format = detectTextFormat(output);
2707
+ if (ccrAvailable && format === "diff" && config.compression.diff.enabled) {
2708
+ const result = compressDiffOutput(output, config.compression.diff, runtime.ccrStore);
2709
+ if (result.applied) return result;
2710
+ } else if (ccrAvailable && format === "log" && config.compression.log.enabled) {
2711
+ const result = compressLogOutput(output, config.compression.log, runtime.ccrStore);
2712
+ if (result.applied) return result;
2713
+ } else if (ccrAvailable && format === "search" && config.compression.search.enabled) {
2714
+ const result = compressSearchOutput(output, config.compression.search, runtime.ccrStore);
2715
+ if (result.applied) return result;
2716
+ }
2717
+ if (ccrAvailable && config.compression.text.enabled) {
2718
+ const result = compressTextOutput(output, query, config.compression.text, runtime.ccrStore);
2719
+ if (result.applied) return result;
2720
+ }
2721
+ return notApplied4(output);
2722
+ }
2723
+
1986
2724
  // src/nodes/agentCore.ts
1987
2725
  function createAgentCoreNode(opts) {
1988
2726
  return async (state) => {
@@ -2082,6 +2820,42 @@ function createAgentCoreNode(opts) {
2082
2820
  const streamingEnabled = Boolean(state.ctx?.__streaming);
2083
2821
  const cancellationToken = state.ctx?.__cancellationToken;
2084
2822
  const abortSignal = state.ctx?.__abortSignal;
2823
+ const resolvedForCachePilot = getResolvedSmartConfig(opts, runtime);
2824
+ if (resolvedForCachePilot.contextPilot.enabled && resolvedForCachePilot.contextPilot.cacheAlignment.enabled) {
2825
+ const ctxForCacheWarning = state.ctx = state.ctx || {};
2826
+ if (!ctxForCacheWarning.__contextPilotCacheWarned) {
2827
+ const systemMessages = (state.messages || []).filter((m) => m?.role === "system");
2828
+ const systemText = systemMessages.map((m) => typeof m.content === "string" ? m.content : "").join("\n");
2829
+ const findings = detectVolatileContent(systemText);
2830
+ if (findings.length > 0) {
2831
+ ctxForCacheWarning.__contextPilotCacheWarned = true;
2832
+ if (resolvedForCachePilot.contextPilot.cacheAlignment.warnOnVolatilePrompt) {
2833
+ const patternCounts = findings.reduce((acc, finding) => {
2834
+ acc[finding.pattern] = (acc[finding.pattern] || 0) + 1;
2835
+ return acc;
2836
+ }, {});
2837
+ onEvent?.({
2838
+ type: "metadata",
2839
+ reason: "context_pilot_cache_alignment",
2840
+ message: "Volatile content detected in system prompt; this may defeat provider-side prompt caching.",
2841
+ patternCounts
2842
+ });
2843
+ recordTraceEvent(traceSession, {
2844
+ type: "metadata",
2845
+ label: "ContextPilot: volatile system prompt content",
2846
+ actor: { scope: "agent", name: actorName, role: "agent" },
2847
+ sections: [
2848
+ {
2849
+ kind: "metadata",
2850
+ label: "Volatile content findings",
2851
+ data: { patternCounts, totalFindings: findings.length }
2852
+ }
2853
+ ]
2854
+ });
2855
+ }
2856
+ }
2857
+ }
2858
+ }
2085
2859
  const responseFormat = runtime.responseFormat;
2086
2860
  const reasoningForCall = state.ctx?.__reasoning;
2087
2861
  const reasoningInvokeOpts = reasoningForCall ? { reasoning: reasoningForCall } : void 0;
@@ -2176,68 +2950,23 @@ function createAgentCoreNode(opts) {
2176
2950
  const id = `${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
2177
2951
  const turn = usageState.perRequest.length + 1;
2178
2952
  const timestamp = (/* @__PURE__ */ new Date()).toISOString();
2179
- const cachedInputTok = normalized.prompt_tokens_details?.cached_tokens;
2180
- usageState.perRequest.push({ id, modelName, usage: normalized, timestamp, turn, cachedInput: cachedInputTok });
2181
- const inputTok = normalized.prompt_tokens;
2182
- const outputTok = normalized.completion_tokens;
2183
- const totalTok = normalized.total_tokens;
2184
- const key = modelName;
2185
- const agg = usageState.totals[key] || { input: 0, output: 0, total: 0, cachedInput: 0 };
2186
- usageState.totals[key] = {
2187
- input: agg.input + (Number(inputTok) || 0),
2188
- output: agg.output + (Number(outputTok) || 0),
2189
- total: agg.total + (Number(totalTok) || 0),
2190
- cachedInput: agg.cachedInput + (Number(cachedInputTok) || 0)
2191
- };
2192
- state.usage = usageState;
2193
- }
2194
- return { messages: messagesWithResponse, usage: state.usage };
2195
- };
2196
- }
2197
-
2198
- // src/utils/content.ts
2199
- function contentToString(content) {
2200
- try {
2201
- if (content == null) return "";
2202
- if (typeof content === "string") return content;
2203
- if (Array.isArray(content)) {
2204
- return content.map((p) => {
2205
- if (!p || typeof p !== "object") return String(p);
2206
- if (p.type === "text") return String(p.text ?? "");
2207
- if (p.type === "image_url") {
2208
- const img = p.image_url;
2209
- const url = typeof img === "string" ? img : img?.url;
2210
- const detail = typeof img === "string" ? void 0 : img?.detail;
2211
- return `[image:${url || "unknown"}${detail ? ` detail=${detail}` : ""}]`;
2212
- }
2213
- return JSON.stringify(p);
2214
- }).join("\n");
2953
+ const cachedInputTok = normalized.prompt_tokens_details?.cached_tokens;
2954
+ usageState.perRequest.push({ id, modelName, usage: normalized, timestamp, turn, cachedInput: cachedInputTok });
2955
+ const inputTok = normalized.prompt_tokens;
2956
+ const outputTok = normalized.completion_tokens;
2957
+ const totalTok = normalized.total_tokens;
2958
+ const key = modelName;
2959
+ const agg = usageState.totals[key] || { input: 0, output: 0, total: 0, cachedInput: 0 };
2960
+ usageState.totals[key] = {
2961
+ input: agg.input + (Number(inputTok) || 0),
2962
+ output: agg.output + (Number(outputTok) || 0),
2963
+ total: agg.total + (Number(totalTok) || 0),
2964
+ cachedInput: agg.cachedInput + (Number(cachedInputTok) || 0)
2965
+ };
2966
+ state.usage = usageState;
2215
2967
  }
2216
- return JSON.stringify(content);
2217
- } catch {
2218
- return String(content);
2219
- }
2220
- }
2221
- function mergeContentsToString(contents) {
2222
- return contents.map((c) => contentToString(c)).join("\n");
2223
- }
2224
- function safeStringify(value, pretty = false) {
2225
- if (value == null) return "";
2226
- if (typeof value === "string") return value;
2227
- try {
2228
- return JSON.stringify(value, null, pretty ? 2 : void 0) ?? String(value);
2229
- } catch {
2230
- return String(value);
2231
- }
2232
- }
2233
- function extractMessageText(message) {
2234
- if (!message) return "";
2235
- const content = message.content;
2236
- if (typeof content === "string") return content;
2237
- if (Array.isArray(content)) {
2238
- return content.map((part) => typeof part === "string" ? part : part?.text ?? part?.content ?? "").join("");
2239
- }
2240
- return "";
2968
+ return { messages: messagesWithResponse, usage: state.usage };
2969
+ };
2241
2970
  }
2242
2971
 
2243
2972
  // src/utils/traceSections.ts
@@ -2278,217 +3007,6 @@ function extractToolItems(output) {
2278
3007
  });
2279
3008
  }
2280
3009
 
2281
- // src/smart/runtimeConfig.ts
2282
- var DEFAULT_CRITICAL_TOOLS = ["response", "manage_todo_list", "get_tool_response"];
2283
- var BASE_DEFAULTS = {
2284
- limits: { maxToolCalls: 20, maxParallelTools: 5, maxContextTokens: 96e3, maxTotalOutputTokens: 0, maxCostUsd: 0, maxWallClockMs: 0 },
2285
- summarization: {
2286
- enable: true,
2287
- maxTokens: 96e3,
2288
- summaryTriggerTokens: 72e3,
2289
- summaryPromptMaxTokens: 12e3,
2290
- summaryCompressionRatioTarget: 0.45,
2291
- summaryMode: "incremental",
2292
- promptTemplate: "",
2293
- toolFreeCall: true,
2294
- integrityCheck: true
2295
- },
2296
- context: {
2297
- policy: "hybrid",
2298
- lastTurnsToKeep: 16,
2299
- toolResponsePolicy: "summarize_archive",
2300
- budget: {
2301
- systemReserveTokens: 2e3,
2302
- goalsReserveTokens: 2e3,
2303
- recentTurnsReserveTokens: 18e3,
2304
- toolResponseReserveTokens: 9e3
2305
- }
2306
- },
2307
- planning: {
2308
- mode: "off",
2309
- replanPolicy: "on_failure",
2310
- everyNSteps: 0
2311
- },
2312
- memory: {
2313
- provider: "inMemory",
2314
- scope: "session",
2315
- writePolicy: "auto_important",
2316
- readPolicy: "hybrid"
2317
- },
2318
- delegation: {
2319
- mode: "role_based",
2320
- maxDelegationDepth: 2,
2321
- maxChildCalls: 6,
2322
- maxParallelChild: 3,
2323
- childContextPolicy: "scoped",
2324
- requireJsonOutputContract: true
2325
- },
2326
- toolResponses: {
2327
- maxToolResponseChars: 32e3,
2328
- maxToolResponseTokens: 8e3,
2329
- defaultPolicy: "summarize_archive",
2330
- toolResponseRetentionByTool: {},
2331
- criticalTools: [...DEFAULT_CRITICAL_TOOLS],
2332
- schemaValidation: "strict"
2333
- }
2334
- };
2335
- function buildProfile(overrides) {
2336
- return {
2337
- limits: { ...BASE_DEFAULTS.limits, ...overrides.limits },
2338
- summarization: { ...BASE_DEFAULTS.summarization, ...overrides.summarization },
2339
- context: {
2340
- ...BASE_DEFAULTS.context,
2341
- ...overrides.context,
2342
- budget: { ...BASE_DEFAULTS.context.budget, ...overrides.context?.budget }
2343
- },
2344
- planning: { ...BASE_DEFAULTS.planning, ...overrides.planning },
2345
- memory: { ...BASE_DEFAULTS.memory, ...overrides.memory },
2346
- delegation: { ...BASE_DEFAULTS.delegation, ...overrides.delegation },
2347
- toolResponses: {
2348
- ...BASE_DEFAULTS.toolResponses,
2349
- ...overrides.toolResponses,
2350
- criticalTools: overrides.toolResponses?.criticalTools ?? [...DEFAULT_CRITICAL_TOOLS],
2351
- toolResponseRetentionByTool: overrides.toolResponses?.toolResponseRetentionByTool ?? {}
2352
- }
2353
- };
2354
- }
2355
- var DEFAULT_PROFILE_CONFIGS = {
2356
- fast: buildProfile({
2357
- limits: { maxToolCalls: 8, maxParallelTools: 3, maxContextTokens: 32e3 },
2358
- summarization: {
2359
- maxTokens: 32e3,
2360
- summaryTriggerTokens: 24e3,
2361
- summaryPromptMaxTokens: 6e3,
2362
- summaryCompressionRatioTarget: 0.5
2363
- },
2364
- context: {
2365
- lastTurnsToKeep: 8,
2366
- toolResponsePolicy: "keep_structured",
2367
- budget: { systemReserveTokens: 1500, goalsReserveTokens: 1200, recentTurnsReserveTokens: 6e3, toolResponseReserveTokens: 3500 }
2368
- },
2369
- memory: { readPolicy: "recent_only" },
2370
- delegation: { mode: "off", maxDelegationDepth: 1, maxChildCalls: 2, maxParallelChild: 1, childContextPolicy: "minimal" },
2371
- toolResponses: { maxToolResponseChars: 16e3, maxToolResponseTokens: 4e3 }
2372
- }),
2373
- balanced: buildProfile({}),
2374
- deep: buildProfile({
2375
- limits: { maxToolCalls: 40, maxParallelTools: 8, maxContextTokens: 2e5 },
2376
- summarization: {
2377
- maxTokens: 2e5,
2378
- summaryTriggerTokens: 15e4,
2379
- summaryPromptMaxTokens: 16e3,
2380
- summaryCompressionRatioTarget: 0.4
2381
- },
2382
- context: {
2383
- lastTurnsToKeep: 30,
2384
- budget: { systemReserveTokens: 2500, goalsReserveTokens: 2500, recentTurnsReserveTokens: 36e3, toolResponseReserveTokens: 18e3 }
2385
- },
2386
- memory: { scope: "workspace" },
2387
- delegation: { maxDelegationDepth: 3, maxChildCalls: 10, maxParallelChild: 4 },
2388
- toolResponses: { maxToolResponseChars: 64e3, maxToolResponseTokens: 16e3 }
2389
- }),
2390
- research: buildProfile({
2391
- limits: { maxToolCalls: 80, maxParallelTools: 10, maxContextTokens: 4e5 },
2392
- summarization: {
2393
- maxTokens: 4e5,
2394
- summaryTriggerTokens: 3e5,
2395
- summaryPromptMaxTokens: 24e3,
2396
- summaryCompressionRatioTarget: 0.35
2397
- },
2398
- context: {
2399
- lastTurnsToKeep: 60,
2400
- budget: { systemReserveTokens: 3e3, goalsReserveTokens: 3e3, recentTurnsReserveTokens: 72e3, toolResponseReserveTokens: 32e3 }
2401
- },
2402
- memory: { scope: "workspace" },
2403
- delegation: { mode: "automatic", maxDelegationDepth: 4, maxChildCalls: 16, maxParallelChild: 6, childContextPolicy: "full" },
2404
- toolResponses: { maxToolResponseChars: 96e3, maxToolResponseTokens: 24e3 }
2405
- })
2406
- };
2407
- function mergeLimits(base, override) {
2408
- return {
2409
- maxToolCalls: override?.maxToolCalls ?? base.maxToolCalls,
2410
- maxParallelTools: override?.maxParallelTools ?? base.maxParallelTools,
2411
- maxContextTokens: override?.maxContextTokens ?? base.maxContextTokens,
2412
- maxTotalOutputTokens: override?.maxTotalOutputTokens ?? base.maxTotalOutputTokens ?? 0,
2413
- maxCostUsd: override?.maxCostUsd ?? base.maxCostUsd ?? 0,
2414
- maxWallClockMs: override?.maxWallClockMs ?? base.maxWallClockMs ?? 0
2415
- };
2416
- }
2417
- function resolveBaseProfile(opts, runtimeProfile) {
2418
- if (opts.customProfile?.extends) return opts.customProfile.extends;
2419
- if (runtimeProfile !== "custom") return runtimeProfile;
2420
- return "balanced";
2421
- }
2422
- function normalizeSmartAgentOptions(opts) {
2423
- const runtimeProfile = opts.runtimeProfile ?? (opts.customProfile ? "custom" : "balanced");
2424
- const baseProfile = resolveBaseProfile(opts, runtimeProfile);
2425
- const preset = DEFAULT_PROFILE_CONFIGS[baseProfile];
2426
- const customProfile = opts.customProfile || {};
2427
- const useTodoList = opts.useTodoList === true;
2428
- const summarizationDisabled = opts.summarization === false;
2429
- const summarizationOverride = typeof opts.summarization === "object" ? opts.summarization : {};
2430
- const planningMode = opts.planning?.mode ?? customProfile.planning?.mode ?? (useTodoList ? "todo" : preset.planning.mode);
2431
- const memoryStore = opts.memory?.store ?? customProfile.memory?.store;
2432
- const contextToolResponsePolicy = opts.context?.toolResponsePolicy ?? customProfile.context?.toolResponsePolicy ?? preset.context.toolResponsePolicy;
2433
- return {
2434
- runtimeProfile,
2435
- baseProfile,
2436
- limits: mergeLimits(mergeLimits(preset.limits, customProfile.limits), opts.limits),
2437
- summarization: {
2438
- ...preset.summarization,
2439
- ...customProfile.summarization || {},
2440
- ...summarizationOverride,
2441
- enable: summarizationDisabled ? false : summarizationOverride.enable ?? customProfile.summarization?.enable ?? preset.summarization.enable,
2442
- maxTokens: summarizationOverride.maxTokens ?? opts.limits?.maxContextTokens ?? customProfile.summarization?.maxTokens ?? preset.summarization.maxTokens,
2443
- summaryTriggerTokens: summarizationOverride.summaryTriggerTokens ?? summarizationOverride.maxTokens ?? opts.limits?.maxContextTokens ?? customProfile.summarization?.summaryTriggerTokens ?? customProfile.summarization?.maxTokens ?? preset.summarization.summaryTriggerTokens,
2444
- promptTemplate: summarizationOverride.promptTemplate ?? customProfile.summarization?.promptTemplate ?? preset.summarization.promptTemplate
2445
- },
2446
- context: {
2447
- ...preset.context,
2448
- ...customProfile.context || {},
2449
- ...opts.context || {},
2450
- budget: {
2451
- ...preset.context.budget,
2452
- ...customProfile.context?.budget || {},
2453
- ...opts.context?.budget || {}
2454
- },
2455
- toolResponsePolicy: contextToolResponsePolicy
2456
- },
2457
- planning: {
2458
- ...preset.planning,
2459
- ...customProfile.planning || {},
2460
- ...opts.planning || {},
2461
- mode: planningMode
2462
- },
2463
- memory: {
2464
- ...preset.memory,
2465
- ...customProfile.memory || {},
2466
- ...opts.memory || {},
2467
- store: memoryStore
2468
- },
2469
- delegation: {
2470
- ...preset.delegation,
2471
- ...customProfile.delegation || {},
2472
- ...opts.delegation || {}
2473
- },
2474
- toolResponses: {
2475
- ...preset.toolResponses,
2476
- ...customProfile.toolResponses || {},
2477
- ...opts.toolResponses || {},
2478
- defaultPolicy: opts.toolResponses?.defaultPolicy ?? customProfile.toolResponses?.defaultPolicy ?? contextToolResponsePolicy,
2479
- toolResponseRetentionByTool: {
2480
- ...preset.toolResponses.toolResponseRetentionByTool,
2481
- ...customProfile.toolResponses?.toolResponseRetentionByTool || {},
2482
- ...opts.toolResponses?.toolResponseRetentionByTool || {}
2483
- },
2484
- criticalTools: opts.toolResponses?.criticalTools ?? customProfile.toolResponses?.criticalTools ?? preset.toolResponses.criticalTools
2485
- }
2486
- };
2487
- }
2488
- function getResolvedSmartConfig(opts, runtime) {
2489
- return runtime?.smart || normalizeSmartAgentOptions(opts);
2490
- }
2491
-
2492
3010
  // src/smart/toolResponses.ts
2493
3011
  init_utilTokens();
2494
3012
  function summarizeObject(value) {
@@ -2730,6 +3248,23 @@ function createToolsNode(initialTools, opts) {
2730
3248
  outputSchema: opts?.outputSchema
2731
3249
  };
2732
3250
  const resolved = getResolvedSmartConfig(opts || {}, runtime);
3251
+ const contextPilotRuntime = state.ctx?.__contextPilot;
3252
+ const contextPilotQuery = contextPilotRuntime ? extractLatestUserQuery(state.messages) : "";
3253
+ const maybeCompressToolOutput = (toolNameForCompression, rawValue, executionIdForCompression) => {
3254
+ if (!contextPilotRuntime || !resolved.contextPilot.enabled) return { output: rawValue };
3255
+ if (resolved.toolResponses.criticalTools.includes(toolNameForCompression)) return { output: rawValue };
3256
+ const result = compressToolOutput({
3257
+ toolName: toolNameForCompression,
3258
+ output: rawValue,
3259
+ query: contextPilotQuery,
3260
+ executionId: executionIdForCompression,
3261
+ config: resolved.contextPilot,
3262
+ runtime: contextPilotRuntime
3263
+ });
3264
+ if (!result.applied) return { output: rawValue };
3265
+ const { output: compressedValue, ...stats } = result;
3266
+ return { output: compressedValue, stats };
3267
+ };
2733
3268
  const activeTools = runtime.tools;
2734
3269
  const toolByName = /* @__PURE__ */ new Map();
2735
3270
  for (const tool of activeTools) toolByName.set(tool.name, tool);
@@ -2967,12 +3502,13 @@ function createToolsNode(initialTools, opts) {
2967
3502
  try {
2968
3503
  if (cachedHit !== void 0) {
2969
3504
  const executionId2 = nanoid.nanoid();
2970
- const responsePolicy2 = applyToolResponseHardCap(toolName, cachedHit, executionId2, resolved);
3505
+ const { output: compressedCachedHit, stats: cachedContextPilotStats } = maybeCompressToolOutput(toolName, cachedHit, executionId2);
3506
+ const responsePolicy2 = applyToolResponseHardCap(toolName, compressedCachedHit, executionId2, resolved);
2971
3507
  toolHistory.push({
2972
3508
  executionId: executionId2,
2973
3509
  toolName,
2974
3510
  args,
2975
- output: cachedHit,
3511
+ output: compressedCachedHit,
2976
3512
  rawOutput: cachedHit,
2977
3513
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
2978
3514
  tool_call_id: tc.id,
@@ -2981,7 +3517,8 @@ function createToolsNode(initialTools, opts) {
2981
3517
  classification: responsePolicy2.classification,
2982
3518
  retentionPolicy: "keep_full",
2983
3519
  fromCache: true,
2984
- status: "success"
3520
+ status: "success",
3521
+ contextPilot: cachedContextPilotStats
2985
3522
  });
2986
3523
  push({ role: "tool", content: responsePolicy2.content, tool_call_id: tc.id || `${tc.name}_${toolCount}`, name: tc.name });
2987
3524
  onEvent?.({ type: "tool_call", phase: "success", name: toolName, id: tc.id, args, result: cachedHit, durationMs: 0 });
@@ -3014,7 +3551,8 @@ function createToolsNode(initialTools, opts) {
3014
3551
  retentionPolicy: "keep_full",
3015
3552
  originalTokenCount: responsePolicy2.tokenCount,
3016
3553
  truncated: responsePolicy2.truncated,
3017
- fromCache: true
3554
+ fromCache: true,
3555
+ contextPilot: cachedContextPilotStats
3018
3556
  }
3019
3557
  });
3020
3558
  toolCount += 1;
@@ -3119,13 +3657,14 @@ function createToolsNode(initialTools, opts) {
3119
3657
  state.ctx.__structuredOutputParsed = output.data;
3120
3658
  state.ctx.__finalizedDueToStructuredOutput = true;
3121
3659
  }
3122
- const responsePolicy = applyToolResponseHardCap(toolName, output, executionId, resolved);
3660
+ const { output: compressedOutput, stats: contextPilotStats } = maybeCompressToolOutput(toolName, output, executionId);
3661
+ const responsePolicy = applyToolResponseHardCap(toolName, compressedOutput, executionId, resolved);
3123
3662
  const timestamp = (/* @__PURE__ */ new Date()).toISOString();
3124
3663
  toolHistory.push({
3125
3664
  executionId,
3126
3665
  toolName,
3127
3666
  args,
3128
- output,
3667
+ output: compressedOutput,
3129
3668
  rawOutput: output,
3130
3669
  timestamp,
3131
3670
  tool_call_id: tc.id,
@@ -3135,7 +3674,8 @@ function createToolsNode(initialTools, opts) {
3135
3674
  retentionPolicy: "keep_full",
3136
3675
  summary: void 0,
3137
3676
  archiveId: void 0,
3138
- status: "success"
3677
+ status: "success",
3678
+ contextPilot: contextPilotStats
3139
3679
  });
3140
3680
  push({ role: "tool", content: responsePolicy.content, tool_call_id: tc.id || `${tc.name}_${toolCount}`, name: tc.name });
3141
3681
  onEvent?.({ type: "tool_call", phase: "success", name: toolName, id: tc.id, args, result: output, durationMs });
@@ -3173,7 +3713,8 @@ function createToolsNode(initialTools, opts) {
3173
3713
  classification: responsePolicy.classification,
3174
3714
  retentionPolicy: "keep_full",
3175
3715
  originalTokenCount: responsePolicy.tokenCount,
3176
- truncated: responsePolicy.truncated
3716
+ truncated: responsePolicy.truncated,
3717
+ contextPilot: contextPilotStats
3177
3718
  }
3178
3719
  });
3179
3720
  toolCount += 1;
@@ -3812,7 +4353,8 @@ var DISALLOWED_CTX_KEYS = /* @__PURE__ */ new Set([
3812
4353
  "__traceSession",
3813
4354
  "__paused",
3814
4355
  "__cancellationToken",
3815
- "__abortSignal"
4356
+ "__abortSignal",
4357
+ "__contextPilot"
3816
4358
  ]);
3817
4359
  var clone = (value) => {
3818
4360
  if (typeof globalThis.structuredClone === "function") {
@@ -4763,7 +5305,7 @@ function createAgent(opts) {
4763
5305
  if (toolCalls.length === 0) {
4764
5306
  if (soManager && !state.ctx?.__finalizedDueToStructuredOutput && !state.ctx?.__structuredOutputForceFinalize) {
4765
5307
  if (soManager.strategy.kind === "native") {
4766
- const assistantText = extractMessageText(lastMsg);
5308
+ const assistantText = extractMessageText2(lastMsg);
4767
5309
  if (assistantText) {
4768
5310
  const parsed = soManager.parseFromContent(assistantText);
4769
5311
  if (parsed.success) {
@@ -4816,7 +5358,7 @@ function createAgent(opts) {
4816
5358
  if (soManager && !state.ctx?.__finalizedDueToStructuredOutput) {
4817
5359
  const lastForParse = state.messages[state.messages.length - 1];
4818
5360
  if (lastForParse?.role === "assistant") {
4819
- const assistantText = extractMessageText(lastForParse);
5361
+ const assistantText = extractMessageText2(lastForParse);
4820
5362
  if (assistantText) {
4821
5363
  const parsed = soManager.parseFromContent(assistantText);
4822
5364
  if (parsed.success) {
@@ -4925,6 +5467,10 @@ function createAgent(opts) {
4925
5467
  if (config?.timeoutMs && config.timeoutMs > 0) {
4926
5468
  ctx.__deadline = Date.now() + config.timeoutMs;
4927
5469
  }
5470
+ if (!ctx.__contextPilot) {
5471
+ const resolvedForContextPilot = getResolvedSmartConfig(opts, runtime);
5472
+ ctx.__contextPilot = createContextPilotRuntime(resolvedForContextPilot.contextPilot);
5473
+ }
4928
5474
  const runtimeWithInvokeLimits = config?.limits ? { ...runtime, limits: { ...runtime.limits || {}, ...config.limits } } : runtime;
4929
5475
  const initial = {
4930
5476
  messages: input.messages || [],
@@ -4969,7 +5515,7 @@ function createAgent(opts) {
4969
5515
  const isTransientSummarizationExit = !!res.ctx?.__needsSummarization;
4970
5516
  const finalAssistantMsg = isTransientSummarizationExit ? void 0 : getLastAssistantMessage(res.messages);
4971
5517
  const finalIsSyntheticSummary = !isTransientSummarizationExit && finalAssistantMsg && isSyntheticSummaryMessage(finalAssistantMsg);
4972
- const content = isTransientSummarizationExit || finalIsSyntheticSummary ? "" : extractMessageText(finalAssistantMsg);
5518
+ const content = isTransientSummarizationExit || finalIsSyntheticSummary ? "" : extractMessageText2(finalAssistantMsg);
4973
5519
  let parsed = void 0;
4974
5520
  let outputError = void 0;
4975
5521
  if (soManager) {
@@ -5278,7 +5824,7 @@ function renderMemoryBlock(facts) {
5278
5824
  function clampToBudget(messages, maxContextTokens) {
5279
5825
  let working = [...messages];
5280
5826
  while (working.length > 2) {
5281
- const tokenCount = countApproxTokens(working.map(extractMessageText).join("\n"));
5827
+ const tokenCount = countApproxTokens(working.map(extractMessageText2).join("\n"));
5282
5828
  if (tokenCount <= maxContextTokens) return working;
5283
5829
  const firstNonSystem = working.findIndex((message, index) => !(index === 0 && message.role === "system"));
5284
5830
  if (firstNonSystem < 0) break;
@@ -6151,6 +6697,13 @@ function createGetToolResponseTool(stateRef) {
6151
6697
  if (execution) {
6152
6698
  return execution.rawOutput || execution.output;
6153
6699
  }
6700
+ const ccrStore = stateRef.ctx?.__contextPilot?.ccrStore;
6701
+ if (ccrStore && typeof ccrStore.retrieve === "function") {
6702
+ const recovered = ccrStore.retrieve(executionId);
6703
+ if (recovered !== void 0) {
6704
+ return recovered;
6705
+ }
6706
+ }
6154
6707
  return "Execution not found. Please check the executionId.";
6155
6708
  }
6156
6709
  });
@@ -7082,7 +7635,7 @@ function createSmartAgent(opts) {
7082
7635
  ].join("\n");
7083
7636
  function latestUserPrompt(messages) {
7084
7637
  const latest = [...messages].reverse().find((message) => message.role === "user");
7085
- return latest ? extractMessageText(latest) : "";
7638
+ return latest ? extractMessageText2(latest) : "";
7086
7639
  }
7087
7640
  async function syncMemory(state) {
7088
7641
  const query = latestUserPrompt(state.messages || []);
@@ -10189,10 +10742,13 @@ exports.AnthropicProvider = AnthropicProvider;
10189
10742
  exports.AzureProvider = AzureProvider;
10190
10743
  exports.BaseProvider = BaseProvider;
10191
10744
  exports.BedrockProvider = BedrockProvider;
10745
+ exports.CCRStore = CCRStore;
10746
+ exports.CONTEXT_PILOT_JSON_MARKER_KEY = CONTEXT_PILOT_JSON_MARKER_KEY;
10192
10747
  exports.DEFAULT_PROFILE_CONFIGS = DEFAULT_PROFILE_CONFIGS;
10193
10748
  exports.DEFAULT_SKILL_POLICY = DEFAULT_SKILL_POLICY;
10194
10749
  exports.DEFAULT_SUBAGENT_POLICY = DEFAULT_SUBAGENT_POLICY;
10195
10750
  exports.DEFAULT_SUBAGENT_TOOL_NAMES = DEFAULT_SUBAGENT_TOOL_NAMES;
10751
+ exports.DedupTracker = DedupTracker;
10196
10752
  exports.GuardrailPhase = GuardrailPhase;
10197
10753
  exports.InMemoryMemoryStore = InMemoryMemoryStore;
10198
10754
  exports.NativeJsonSchemaStrategy = NativeJsonSchemaStrategy;
@@ -10214,6 +10770,12 @@ exports.captureSnapshot = captureSnapshot;
10214
10770
  exports.codePresenceRule = codePresenceRule;
10215
10771
  exports.cognipeerSink = cognipeerSink;
10216
10772
  exports.composeToolSets = composeToolSets;
10773
+ exports.compressDiffOutput = compressDiffOutput;
10774
+ exports.compressJsonOutput = compressJsonOutput;
10775
+ exports.compressLogOutput = compressLogOutput;
10776
+ exports.compressSearchOutput = compressSearchOutput;
10777
+ exports.compressTextOutput = compressTextOutput;
10778
+ exports.compressToolOutput = compressToolOutput;
10217
10779
  exports.countApproxTokens = countApproxTokens;
10218
10780
  exports.countMessagesTokens = countMessagesTokens;
10219
10781
  exports.createAgent = createAgent;
@@ -10221,6 +10783,7 @@ exports.createAgentNode = createAgentNode;
10221
10783
  exports.createAskUserQuestionTool = createAskUserQuestionTool;
10222
10784
  exports.createBindSkillToolsTool = createBindSkillToolsTool;
10223
10785
  exports.createCodeGuardrail = createCodeGuardrail;
10786
+ exports.createContextPilotRuntime = createContextPilotRuntime;
10224
10787
  exports.createContextSummarizeNode = createContextSummarizeNode;
10225
10788
  exports.createContextTools = createContextTools;
10226
10789
  exports.createDelegateTool = createDelegateTool;
@@ -10246,8 +10809,11 @@ exports.customCallbackRule = customCallbackRule;
10246
10809
  exports.customSink = customSink;
10247
10810
  exports.dedupeToolsByName = dedupeToolsByName;
10248
10811
  exports.defaultTokenCounter = defaultTokenCounter;
10812
+ exports.detectTextFormat = detectTextFormat;
10813
+ exports.detectVolatileContent = detectVolatileContent;
10249
10814
  exports.emptyUsage = emptyUsage;
10250
10815
  exports.evaluateGuardrails = evaluateGuardrails;
10816
+ exports.extractLatestUserQuery = extractLatestUserQuery;
10251
10817
  exports.fileSink = fileSink;
10252
10818
  exports.findSubagent = findSubagent;
10253
10819
  exports.formatZodError = formatZodError;
@@ -10280,9 +10846,12 @@ exports.resolveToolApprovalState = resolveToolApprovalState;
10280
10846
  exports.resolveUserQuestionState = resolveUserQuestionState;
10281
10847
  exports.restoreSnapshot = restoreSnapshot;
10282
10848
  exports.runSmartAgentEvalHarness = runSmartAgentEvalHarness;
10849
+ exports.scoreItemsByRelevance = scoreItemsByRelevance;
10283
10850
  exports.seedChildMessages = seedChildMessages;
10851
+ exports.selectTopIndicesInOrder = selectTopIndicesInOrder;
10284
10852
  exports.setTokenCounter = setTokenCounter;
10285
10853
  exports.startStreamingSession = startStreamingSession;
10854
+ exports.tokenize = tokenize;
10286
10855
  exports.traceSessionToOtlp = traceSessionToOtlp;
10287
10856
  exports.validateReasoningConfig = validateReasoningConfig;
10288
10857
  exports.withTools = withTools;