@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.mjs CHANGED
@@ -5,7 +5,7 @@ import fs from 'fs';
5
5
  import path from 'path';
6
6
  import { Buffer as Buffer$1 } from 'buffer';
7
7
  import { nanoid } from 'nanoid';
8
- import crypto, { randomUUID, createHash, createHmac } from 'crypto';
8
+ import crypto, { createHash, randomUUID, createHmac } from 'crypto';
9
9
  import AjvModule from 'ajv';
10
10
 
11
11
  var __defProp = Object.defineProperty;
@@ -42,7 +42,7 @@ function getTokenCounter() {
42
42
  function countApproxTokens(text) {
43
43
  return activeTokenCounter(text || "");
44
44
  }
45
- function extractMessageText2(m) {
45
+ function extractMessageText(m) {
46
46
  if (!m) return "";
47
47
  const parts = [];
48
48
  parts.push(m.role || "");
@@ -92,7 +92,7 @@ function extractMessageText2(m) {
92
92
  }
93
93
  function countMessagesTokens(messages) {
94
94
  if (!Array.isArray(messages) || messages.length === 0) return 0;
95
- const allText = messages.map(extractMessageText2).join("\n");
95
+ const allText = messages.map(extractMessageText).join("\n");
96
96
  return countApproxTokens(allText) + messages.length * 4;
97
97
  }
98
98
  var activeTokenCounter;
@@ -1078,7 +1078,35 @@ function buildConfigSnapshot(runtime) {
1078
1078
  sink: snapshotSink(runtime)
1079
1079
  };
1080
1080
  }
1081
- async function postTraceSession(url, headers, payload) {
1081
+ var TRACE_HTTP_MAX_ATTEMPTS = 4;
1082
+ var TRACE_HTTP_ATTEMPT_TIMEOUT_MS = 8e3;
1083
+ var TRACE_HTTP_RETRYABLE_STATUS = /* @__PURE__ */ new Set([404, 408, 425, 429, 500, 502, 503, 504]);
1084
+ var TRACE_HTTP_RETRY_BASE_MS = 250;
1085
+ var TRACE_HTTP_RETRY_MAX_MS = 4e3;
1086
+ var RetryableHttpError = class extends Error {
1087
+ constructor(status, message, retryAfterMs) {
1088
+ super(message);
1089
+ this.name = "RetryableHttpError";
1090
+ this.status = status;
1091
+ this.retryAfterMs = retryAfterMs;
1092
+ }
1093
+ };
1094
+ function traceSleep(ms) {
1095
+ return new Promise((resolve) => setTimeout(resolve, ms));
1096
+ }
1097
+ function traceBackoffDelay(attempt, baseMs, maxMs) {
1098
+ const exp = Math.min(maxMs, baseMs * 2 ** (attempt - 1));
1099
+ return Math.floor(Math.random() * exp);
1100
+ }
1101
+ function parseRetryAfterMs(headerValue) {
1102
+ if (!headerValue) return void 0;
1103
+ const seconds = Number(headerValue);
1104
+ if (Number.isFinite(seconds)) return Math.max(0, seconds * 1e3);
1105
+ const dateMs = Date.parse(headerValue);
1106
+ if (Number.isFinite(dateMs)) return Math.max(0, dateMs - Date.now());
1107
+ return void 0;
1108
+ }
1109
+ async function postJsonOnce(url, headers, body) {
1082
1110
  const fetchFn = typeof globalThis.fetch === "function" ? globalThis.fetch.bind(globalThis) : void 0;
1083
1111
  if (!fetchFn) {
1084
1112
  throw new Error("HTTP sink requires fetch to be available in this runtime.");
@@ -1087,135 +1115,71 @@ async function postTraceSession(url, headers, payload) {
1087
1115
  if (!Object.keys(finalHeaders).some((key) => key.toLowerCase() === "content-type")) {
1088
1116
  finalHeaders["content-type"] = "application/json";
1089
1117
  }
1118
+ const controller = new AbortController();
1119
+ const timer = setTimeout(() => controller.abort(), TRACE_HTTP_ATTEMPT_TIMEOUT_MS);
1120
+ let response;
1090
1121
  try {
1091
- const response = await fetchFn(url, {
1122
+ response = await fetchFn(url, {
1092
1123
  method: "POST",
1093
1124
  headers: finalHeaders,
1094
- body: JSON.stringify(payload)
1125
+ body: JSON.stringify(body),
1126
+ signal: controller.signal
1095
1127
  });
1096
- if (!response.ok) {
1097
- let responseText = "";
1098
- try {
1099
- responseText = await response.text();
1100
- } catch {
1101
- }
1102
- const statusLine = `HTTP ${response.status}${response.statusText ? ` ${response.statusText}` : ""}`;
1103
- const bodyPreview = responseText ? ` - ${responseText.slice(0, 200)}` : "";
1104
- const errorMsg = `${statusLine}${bodyPreview}`;
1105
- if (typeof console !== "undefined" && typeof console.error === "function") {
1106
- console.error("[Tracing] Error posting to", url, ":", errorMsg);
1107
- }
1108
- throw new Error(errorMsg);
1109
- }
1110
1128
  } catch (err) {
1111
- const errMsg = err instanceof Error ? err.message : String(err);
1112
- if (typeof console !== "undefined" && typeof console.error === "function") {
1113
- console.error("[Tracing] Failed to post:", errMsg);
1114
- }
1115
- throw err;
1129
+ const message2 = err instanceof Error ? err.message : String(err);
1130
+ throw new RetryableHttpError(0, `network error - ${message2}`);
1131
+ } finally {
1132
+ clearTimeout(timer);
1116
1133
  }
1117
- }
1118
- async function postStreamingSessionStart(baseUrl, headers, payload) {
1119
- const fetchFn = typeof globalThis.fetch === "function" ? globalThis.fetch.bind(globalThis) : void 0;
1120
- if (!fetchFn) {
1121
- throw new Error("HTTP sink requires fetch to be available in this runtime.");
1134
+ if (response.ok) return;
1135
+ let responseText = "";
1136
+ try {
1137
+ responseText = await response.text();
1138
+ } catch {
1122
1139
  }
1123
- const url = `${baseUrl.replace(/\/$/, "")}/stream/${payload.sessionId}/start`;
1124
- const finalHeaders = { ...headers || {} };
1125
- if (!Object.keys(finalHeaders).some((key) => key.toLowerCase() === "content-type")) {
1126
- finalHeaders["content-type"] = "application/json";
1140
+ const statusLine = `HTTP ${response.status}${response.statusText ? ` ${response.statusText}` : ""}`;
1141
+ const bodyPreview = responseText ? ` - ${responseText.slice(0, 200)}` : "";
1142
+ const message = `${statusLine}${bodyPreview}`;
1143
+ if (TRACE_HTTP_RETRYABLE_STATUS.has(response.status)) {
1144
+ throw new RetryableHttpError(response.status, message, parseRetryAfterMs(response.headers.get("retry-after")));
1127
1145
  }
1128
- try {
1129
- const response = await fetchFn(url, {
1130
- method: "POST",
1131
- headers: finalHeaders,
1132
- body: JSON.stringify(payload)
1133
- });
1134
- if (!response.ok) {
1135
- let responseText = "";
1136
- try {
1137
- responseText = await response.text();
1138
- } catch {
1146
+ throw new Error(message);
1147
+ }
1148
+ async function postJsonReliable(url, headers, body, opts = {}) {
1149
+ const maxAttempts = opts.retry === false ? 1 : TRACE_HTTP_MAX_ATTEMPTS;
1150
+ let lastError;
1151
+ for (let attempt = 1; attempt <= maxAttempts; attempt += 1) {
1152
+ try {
1153
+ await postJsonOnce(url, headers, body);
1154
+ return;
1155
+ } catch (err) {
1156
+ lastError = err;
1157
+ if (!(err instanceof RetryableHttpError) || attempt === maxAttempts) {
1158
+ if (typeof console !== "undefined" && typeof console.error === "function") {
1159
+ console.error("[Tracing] Failed to post:", err instanceof Error ? err.message : String(err));
1160
+ }
1161
+ throw err;
1139
1162
  }
1140
- const statusLine = `HTTP ${response.status}${response.statusText ? ` ${response.statusText}` : ""}`;
1141
- const bodyPreview = responseText ? ` - ${responseText.slice(0, 200)}` : "";
1142
- throw new Error(`${statusLine}${bodyPreview}`);
1143
- }
1144
- } catch (err) {
1145
- const errMsg = err instanceof Error ? err.message : String(err);
1146
- if (typeof console !== "undefined" && typeof console.error === "function") {
1147
- console.error("[Tracing] Failed to post session start:", errMsg);
1163
+ const wait = err.retryAfterMs ?? traceBackoffDelay(attempt, TRACE_HTTP_RETRY_BASE_MS, TRACE_HTTP_RETRY_MAX_MS);
1164
+ await traceSleep(Math.min(wait, TRACE_HTTP_RETRY_MAX_MS));
1148
1165
  }
1149
- throw err;
1150
1166
  }
1167
+ throw lastError instanceof Error ? lastError : new Error(String(lastError));
1168
+ }
1169
+ async function postTraceSession(url, headers, payload) {
1170
+ await postJsonReliable(url, headers, payload, { retry: true });
1171
+ }
1172
+ async function postStreamingSessionStart(baseUrl, headers, payload) {
1173
+ const url = `${baseUrl.replace(/\/$/, "")}/stream/${payload.sessionId}/start`;
1174
+ await postJsonReliable(url, headers, payload, { retry: true });
1151
1175
  }
1152
1176
  async function postStreamingEvent(baseUrl, headers, sessionId, event) {
1153
- const fetchFn = typeof globalThis.fetch === "function" ? globalThis.fetch.bind(globalThis) : void 0;
1154
- if (!fetchFn) {
1155
- throw new Error("HTTP sink requires fetch to be available in this runtime.");
1156
- }
1157
1177
  const url = `${baseUrl.replace(/\/$/, "")}/stream/${sessionId}/events`;
1158
- const finalHeaders = { ...headers || {} };
1159
- if (!Object.keys(finalHeaders).some((key) => key.toLowerCase() === "content-type")) {
1160
- finalHeaders["content-type"] = "application/json";
1161
- }
1162
- try {
1163
- const response = await fetchFn(url, {
1164
- method: "POST",
1165
- headers: finalHeaders,
1166
- body: JSON.stringify({ event })
1167
- });
1168
- if (!response.ok) {
1169
- let responseText = "";
1170
- try {
1171
- responseText = await response.text();
1172
- } catch {
1173
- }
1174
- const statusLine = `HTTP ${response.status}${response.statusText ? ` ${response.statusText}` : ""}`;
1175
- const bodyPreview = responseText ? ` - ${responseText.slice(0, 200)}` : "";
1176
- throw new Error(`${statusLine}${bodyPreview}`);
1177
- }
1178
- } catch (err) {
1179
- const errMsg = err instanceof Error ? err.message : String(err);
1180
- if (typeof console !== "undefined" && typeof console.error === "function") {
1181
- console.error("[Tracing] Failed to post streaming event:", errMsg);
1182
- }
1183
- throw err;
1184
- }
1178
+ await postJsonReliable(url, headers, { event }, { retry: false });
1185
1179
  }
1186
1180
  async function postStreamingSessionEnd(baseUrl, headers, payload) {
1187
- const fetchFn = typeof globalThis.fetch === "function" ? globalThis.fetch.bind(globalThis) : void 0;
1188
- if (!fetchFn) {
1189
- throw new Error("HTTP sink requires fetch to be available in this runtime.");
1190
- }
1191
1181
  const url = `${baseUrl.replace(/\/$/, "")}/stream/${payload.sessionId}/end`;
1192
- const finalHeaders = { ...headers || {} };
1193
- if (!Object.keys(finalHeaders).some((key) => key.toLowerCase() === "content-type")) {
1194
- finalHeaders["content-type"] = "application/json";
1195
- }
1196
- try {
1197
- const response = await fetchFn(url, {
1198
- method: "POST",
1199
- headers: finalHeaders,
1200
- body: JSON.stringify(payload)
1201
- });
1202
- if (!response.ok) {
1203
- let responseText = "";
1204
- try {
1205
- responseText = await response.text();
1206
- } catch {
1207
- }
1208
- const statusLine = `HTTP ${response.status}${response.statusText ? ` ${response.statusText}` : ""}`;
1209
- const bodyPreview = responseText ? ` - ${responseText.slice(0, 200)}` : "";
1210
- throw new Error(`${statusLine}${bodyPreview}`);
1211
- }
1212
- } catch (err) {
1213
- const errMsg = err instanceof Error ? err.message : String(err);
1214
- if (typeof console !== "undefined" && typeof console.error === "function") {
1215
- console.error("[Tracing] Failed to post session end:", errMsg);
1216
- }
1217
- throw err;
1218
- }
1182
+ await postJsonReliable(url, headers, payload, { retry: true });
1219
1183
  }
1220
1184
  function isoToUnixNano(iso) {
1221
1185
  const ms = new Date(iso).getTime();
@@ -1588,7 +1552,8 @@ function convertMessageListToSections(messageList) {
1588
1552
  function createTraceSession(opts) {
1589
1553
  const cfg = withDefaults(opts.tracing);
1590
1554
  if (!cfg.enabled) return void 0;
1591
- const sessionId = generateSessionId();
1555
+ const providedSessionId = opts.tracing?.sessionId?.trim();
1556
+ const sessionId = providedSessionId || generateSessionId();
1592
1557
  const traceId = generateTraceId();
1593
1558
  const rootSpanId = generateSpanId();
1594
1559
  const runtime = {
@@ -1596,6 +1561,7 @@ function createTraceSession(opts) {
1596
1561
  traceId,
1597
1562
  rootSpanId,
1598
1563
  threadId: opts.tracing?.threadId,
1564
+ configAgentName: opts.tracing?.agentName?.trim() || void 0,
1599
1565
  startedAt: Date.now(),
1600
1566
  resolvedConfig: cfg,
1601
1567
  events: [],
@@ -1619,11 +1585,12 @@ async function startStreamingSession(session, agentRuntime) {
1619
1585
  if (session.resolvedConfig.mode !== "streaming") return;
1620
1586
  if (session.sessionStarted) return;
1621
1587
  const sink = session.resolvedConfig.sink;
1622
- const agentInfo = agentRuntime ? {
1623
- name: agentRuntime.name || "unknown-agent",
1624
- version: agentRuntime.version,
1625
- model: getModelName(agentRuntime.model) || "unknown-model",
1626
- provider: getProviderName(agentRuntime.model)
1588
+ const resolvedAgentName = session.configAgentName || agentRuntime?.name || "unknown-agent";
1589
+ const agentInfo = agentRuntime || session.configAgentName ? {
1590
+ name: resolvedAgentName,
1591
+ version: agentRuntime?.version,
1592
+ model: getModelName(agentRuntime?.model) || "unknown-model",
1593
+ provider: getProviderName(agentRuntime?.model)
1627
1594
  } : void 0;
1628
1595
  session.agentInfo = agentInfo;
1629
1596
  const configSnapshot = buildConfigSnapshot(session);
@@ -1973,6 +1940,777 @@ function estimatePayloadBytes(value) {
1973
1940
  }
1974
1941
  }
1975
1942
 
1943
+ // src/smart/runtimeConfig.ts
1944
+ var DEFAULT_CRITICAL_TOOLS = ["response", "manage_todo_list", "get_tool_response"];
1945
+ var BASE_DEFAULTS = {
1946
+ limits: { maxToolCalls: 20, maxParallelTools: 5, maxContextTokens: 96e3, maxTotalOutputTokens: 0, maxCostUsd: 0, maxWallClockMs: 0 },
1947
+ summarization: {
1948
+ enable: true,
1949
+ maxTokens: 96e3,
1950
+ summaryTriggerTokens: 72e3,
1951
+ summaryPromptMaxTokens: 12e3,
1952
+ summaryCompressionRatioTarget: 0.45,
1953
+ summaryMode: "incremental",
1954
+ promptTemplate: "",
1955
+ toolFreeCall: true,
1956
+ integrityCheck: true
1957
+ },
1958
+ context: {
1959
+ policy: "hybrid",
1960
+ lastTurnsToKeep: 16,
1961
+ toolResponsePolicy: "summarize_archive",
1962
+ budget: {
1963
+ systemReserveTokens: 2e3,
1964
+ goalsReserveTokens: 2e3,
1965
+ recentTurnsReserveTokens: 18e3,
1966
+ toolResponseReserveTokens: 9e3
1967
+ }
1968
+ },
1969
+ planning: {
1970
+ mode: "off",
1971
+ replanPolicy: "on_failure",
1972
+ everyNSteps: 0
1973
+ },
1974
+ memory: {
1975
+ provider: "inMemory",
1976
+ scope: "session",
1977
+ writePolicy: "auto_important",
1978
+ readPolicy: "hybrid"
1979
+ },
1980
+ delegation: {
1981
+ mode: "role_based",
1982
+ maxDelegationDepth: 2,
1983
+ maxChildCalls: 6,
1984
+ maxParallelChild: 3,
1985
+ childContextPolicy: "scoped",
1986
+ requireJsonOutputContract: true
1987
+ },
1988
+ toolResponses: {
1989
+ maxToolResponseChars: 32e3,
1990
+ maxToolResponseTokens: 8e3,
1991
+ defaultPolicy: "summarize_archive",
1992
+ toolResponseRetentionByTool: {},
1993
+ criticalTools: [...DEFAULT_CRITICAL_TOOLS],
1994
+ schemaValidation: "strict"
1995
+ },
1996
+ contextPilot: {
1997
+ // Opt-in: ContextPilot never alters tool output unless the caller
1998
+ // explicitly passes `contextPilot: { enabled: true }` (or sets `enabled`
1999
+ // via `customProfile`/profile overrides). This preserves backward
2000
+ // compatibility for every existing `createSmartAgent(...)` call site.
2001
+ enabled: false,
2002
+ compression: {
2003
+ json: { enabled: true, targetRatio: 0.35, minItems: 20 },
2004
+ text: { enabled: true, targetRatio: 0.5, minChars: 1200 },
2005
+ diff: { enabled: true, contextLines: 3 },
2006
+ log: { enabled: true, maxLines: 60 },
2007
+ search: { enabled: true, maxMatches: 30 }
2008
+ },
2009
+ ccr: { enabled: true, ttlMs: 30 * 60 * 1e3, maxEntries: 500 },
2010
+ cacheAlignment: { enabled: true, warnOnVolatilePrompt: true },
2011
+ dedup: { enabled: true, minChars: 500 },
2012
+ excludeTools: []
2013
+ }
2014
+ };
2015
+ function mergeContextPilot(base, override) {
2016
+ return {
2017
+ enabled: override?.enabled ?? base.enabled,
2018
+ compression: {
2019
+ json: { ...base.compression.json, ...override?.compression?.json },
2020
+ text: { ...base.compression.text, ...override?.compression?.text },
2021
+ diff: { ...base.compression.diff, ...override?.compression?.diff },
2022
+ log: { ...base.compression.log, ...override?.compression?.log },
2023
+ search: { ...base.compression.search, ...override?.compression?.search }
2024
+ },
2025
+ ccr: { ...base.ccr, ...override?.ccr },
2026
+ cacheAlignment: { ...base.cacheAlignment, ...override?.cacheAlignment },
2027
+ dedup: { ...base.dedup, ...override?.dedup },
2028
+ excludeTools: override?.excludeTools ?? base.excludeTools
2029
+ };
2030
+ }
2031
+ function buildProfile(overrides) {
2032
+ return {
2033
+ limits: { ...BASE_DEFAULTS.limits, ...overrides.limits },
2034
+ summarization: { ...BASE_DEFAULTS.summarization, ...overrides.summarization },
2035
+ context: {
2036
+ ...BASE_DEFAULTS.context,
2037
+ ...overrides.context,
2038
+ budget: { ...BASE_DEFAULTS.context.budget, ...overrides.context?.budget }
2039
+ },
2040
+ planning: { ...BASE_DEFAULTS.planning, ...overrides.planning },
2041
+ memory: { ...BASE_DEFAULTS.memory, ...overrides.memory },
2042
+ delegation: { ...BASE_DEFAULTS.delegation, ...overrides.delegation },
2043
+ toolResponses: {
2044
+ ...BASE_DEFAULTS.toolResponses,
2045
+ ...overrides.toolResponses,
2046
+ criticalTools: overrides.toolResponses?.criticalTools ?? [...DEFAULT_CRITICAL_TOOLS],
2047
+ toolResponseRetentionByTool: overrides.toolResponses?.toolResponseRetentionByTool ?? {}
2048
+ },
2049
+ contextPilot: mergeContextPilot(BASE_DEFAULTS.contextPilot, overrides.contextPilot)
2050
+ };
2051
+ }
2052
+ var DEFAULT_PROFILE_CONFIGS = {
2053
+ fast: buildProfile({
2054
+ limits: { maxToolCalls: 8, maxParallelTools: 3, maxContextTokens: 32e3 },
2055
+ summarization: {
2056
+ maxTokens: 32e3,
2057
+ summaryTriggerTokens: 24e3,
2058
+ summaryPromptMaxTokens: 6e3,
2059
+ summaryCompressionRatioTarget: 0.5
2060
+ },
2061
+ context: {
2062
+ lastTurnsToKeep: 8,
2063
+ toolResponsePolicy: "keep_structured",
2064
+ budget: { systemReserveTokens: 1500, goalsReserveTokens: 1200, recentTurnsReserveTokens: 6e3, toolResponseReserveTokens: 3500 }
2065
+ },
2066
+ memory: { readPolicy: "recent_only" },
2067
+ delegation: { mode: "off", maxDelegationDepth: 1, maxChildCalls: 2, maxParallelChild: 1, childContextPolicy: "minimal" },
2068
+ toolResponses: { maxToolResponseChars: 16e3, maxToolResponseTokens: 4e3 },
2069
+ contextPilot: {
2070
+ compression: {
2071
+ json: { targetRatio: 0.25, minItems: 12 },
2072
+ text: { targetRatio: 0.35, minChars: 800 }
2073
+ }
2074
+ }
2075
+ }),
2076
+ balanced: buildProfile({}),
2077
+ deep: buildProfile({
2078
+ limits: { maxToolCalls: 40, maxParallelTools: 8, maxContextTokens: 2e5 },
2079
+ summarization: {
2080
+ maxTokens: 2e5,
2081
+ summaryTriggerTokens: 15e4,
2082
+ summaryPromptMaxTokens: 16e3,
2083
+ summaryCompressionRatioTarget: 0.4
2084
+ },
2085
+ context: {
2086
+ lastTurnsToKeep: 30,
2087
+ budget: { systemReserveTokens: 2500, goalsReserveTokens: 2500, recentTurnsReserveTokens: 36e3, toolResponseReserveTokens: 18e3 }
2088
+ },
2089
+ memory: { scope: "workspace" },
2090
+ delegation: { maxDelegationDepth: 3, maxChildCalls: 10, maxParallelChild: 4 },
2091
+ toolResponses: { maxToolResponseChars: 64e3, maxToolResponseTokens: 16e3 },
2092
+ contextPilot: {
2093
+ compression: {
2094
+ json: { targetRatio: 0.5, minItems: 30 },
2095
+ text: { targetRatio: 0.6, minChars: 1600 }
2096
+ },
2097
+ ccr: { ttlMs: 60 * 60 * 1e3 }
2098
+ }
2099
+ }),
2100
+ research: buildProfile({
2101
+ limits: { maxToolCalls: 80, maxParallelTools: 10, maxContextTokens: 4e5 },
2102
+ summarization: {
2103
+ maxTokens: 4e5,
2104
+ summaryTriggerTokens: 3e5,
2105
+ summaryPromptMaxTokens: 24e3,
2106
+ summaryCompressionRatioTarget: 0.35
2107
+ },
2108
+ context: {
2109
+ lastTurnsToKeep: 60,
2110
+ budget: { systemReserveTokens: 3e3, goalsReserveTokens: 3e3, recentTurnsReserveTokens: 72e3, toolResponseReserveTokens: 32e3 }
2111
+ },
2112
+ memory: { scope: "workspace" },
2113
+ delegation: { mode: "automatic", maxDelegationDepth: 4, maxChildCalls: 16, maxParallelChild: 6, childContextPolicy: "full" },
2114
+ toolResponses: { maxToolResponseChars: 96e3, maxToolResponseTokens: 24e3 },
2115
+ contextPilot: {
2116
+ compression: {
2117
+ json: { targetRatio: 0.6, minItems: 40 },
2118
+ text: { targetRatio: 0.65, minChars: 2e3 }
2119
+ },
2120
+ ccr: { ttlMs: 2 * 60 * 60 * 1e3, maxEntries: 1e3 }
2121
+ }
2122
+ })
2123
+ };
2124
+ function mergeLimits(base, override) {
2125
+ return {
2126
+ maxToolCalls: override?.maxToolCalls ?? base.maxToolCalls,
2127
+ maxParallelTools: override?.maxParallelTools ?? base.maxParallelTools,
2128
+ maxContextTokens: override?.maxContextTokens ?? base.maxContextTokens,
2129
+ maxTotalOutputTokens: override?.maxTotalOutputTokens ?? base.maxTotalOutputTokens ?? 0,
2130
+ maxCostUsd: override?.maxCostUsd ?? base.maxCostUsd ?? 0,
2131
+ maxWallClockMs: override?.maxWallClockMs ?? base.maxWallClockMs ?? 0
2132
+ };
2133
+ }
2134
+ function resolveBaseProfile(opts, runtimeProfile) {
2135
+ if (opts.customProfile?.extends) return opts.customProfile.extends;
2136
+ if (runtimeProfile !== "custom") return runtimeProfile;
2137
+ return "balanced";
2138
+ }
2139
+ function normalizeSmartAgentOptions(opts) {
2140
+ const runtimeProfile = opts.runtimeProfile ?? (opts.customProfile ? "custom" : "balanced");
2141
+ const baseProfile = resolveBaseProfile(opts, runtimeProfile);
2142
+ const preset = DEFAULT_PROFILE_CONFIGS[baseProfile];
2143
+ const customProfile = opts.customProfile || {};
2144
+ const useTodoList = opts.useTodoList === true;
2145
+ const summarizationDisabled = opts.summarization === false;
2146
+ const summarizationOverride = typeof opts.summarization === "object" ? opts.summarization : {};
2147
+ const planningMode = opts.planning?.mode ?? customProfile.planning?.mode ?? (useTodoList ? "todo" : preset.planning.mode);
2148
+ const memoryStore = opts.memory?.store ?? customProfile.memory?.store;
2149
+ const contextToolResponsePolicy = opts.context?.toolResponsePolicy ?? customProfile.context?.toolResponsePolicy ?? preset.context.toolResponsePolicy;
2150
+ return {
2151
+ runtimeProfile,
2152
+ baseProfile,
2153
+ limits: mergeLimits(mergeLimits(preset.limits, customProfile.limits), opts.limits),
2154
+ summarization: {
2155
+ ...preset.summarization,
2156
+ ...customProfile.summarization || {},
2157
+ ...summarizationOverride,
2158
+ enable: summarizationDisabled ? false : summarizationOverride.enable ?? customProfile.summarization?.enable ?? preset.summarization.enable,
2159
+ maxTokens: summarizationOverride.maxTokens ?? opts.limits?.maxContextTokens ?? customProfile.summarization?.maxTokens ?? preset.summarization.maxTokens,
2160
+ summaryTriggerTokens: summarizationOverride.summaryTriggerTokens ?? summarizationOverride.maxTokens ?? opts.limits?.maxContextTokens ?? customProfile.summarization?.summaryTriggerTokens ?? customProfile.summarization?.maxTokens ?? preset.summarization.summaryTriggerTokens,
2161
+ promptTemplate: summarizationOverride.promptTemplate ?? customProfile.summarization?.promptTemplate ?? preset.summarization.promptTemplate
2162
+ },
2163
+ context: {
2164
+ ...preset.context,
2165
+ ...customProfile.context || {},
2166
+ ...opts.context || {},
2167
+ budget: {
2168
+ ...preset.context.budget,
2169
+ ...customProfile.context?.budget || {},
2170
+ ...opts.context?.budget || {}
2171
+ },
2172
+ toolResponsePolicy: contextToolResponsePolicy
2173
+ },
2174
+ planning: {
2175
+ ...preset.planning,
2176
+ ...customProfile.planning || {},
2177
+ ...opts.planning || {},
2178
+ mode: planningMode
2179
+ },
2180
+ memory: {
2181
+ ...preset.memory,
2182
+ ...customProfile.memory || {},
2183
+ ...opts.memory || {},
2184
+ store: memoryStore
2185
+ },
2186
+ delegation: {
2187
+ ...preset.delegation,
2188
+ ...customProfile.delegation || {},
2189
+ ...opts.delegation || {}
2190
+ },
2191
+ toolResponses: {
2192
+ ...preset.toolResponses,
2193
+ ...customProfile.toolResponses || {},
2194
+ ...opts.toolResponses || {},
2195
+ defaultPolicy: opts.toolResponses?.defaultPolicy ?? customProfile.toolResponses?.defaultPolicy ?? contextToolResponsePolicy,
2196
+ toolResponseRetentionByTool: {
2197
+ ...preset.toolResponses.toolResponseRetentionByTool,
2198
+ ...customProfile.toolResponses?.toolResponseRetentionByTool || {},
2199
+ ...opts.toolResponses?.toolResponseRetentionByTool || {}
2200
+ },
2201
+ criticalTools: opts.toolResponses?.criticalTools ?? customProfile.toolResponses?.criticalTools ?? preset.toolResponses.criticalTools
2202
+ },
2203
+ contextPilot: mergeContextPilot(mergeContextPilot(preset.contextPilot, customProfile.contextPilot), opts.contextPilot)
2204
+ };
2205
+ }
2206
+ function getResolvedSmartConfig(opts, runtime) {
2207
+ return runtime?.smart || normalizeSmartAgentOptions(opts);
2208
+ }
2209
+
2210
+ // src/smart/contextPilot/relevance.ts
2211
+ var STOPWORDS = /* @__PURE__ */ new Set([
2212
+ "the",
2213
+ "a",
2214
+ "an",
2215
+ "and",
2216
+ "or",
2217
+ "but",
2218
+ "if",
2219
+ "then",
2220
+ "else",
2221
+ "for",
2222
+ "of",
2223
+ "in",
2224
+ "on",
2225
+ "at",
2226
+ "to",
2227
+ "by",
2228
+ "with",
2229
+ "is",
2230
+ "are",
2231
+ "was",
2232
+ "were",
2233
+ "be",
2234
+ "been",
2235
+ "being",
2236
+ "this",
2237
+ "that",
2238
+ "these",
2239
+ "those",
2240
+ "it",
2241
+ "its",
2242
+ "as",
2243
+ "from"
2244
+ ]);
2245
+ function tokenize(text) {
2246
+ if (!text) return [];
2247
+ const matches = text.toLowerCase().match(/[\p{L}\p{N}_]+/gu);
2248
+ if (!matches) return [];
2249
+ return matches.filter((token) => token.length > 1 && !STOPWORDS.has(token));
2250
+ }
2251
+ function scoreItemsByRelevance(docs, query, params = {}) {
2252
+ const k1 = params.k1 ?? 1.5;
2253
+ const b = params.b ?? 0.75;
2254
+ const queryTokens = tokenize(query);
2255
+ const docTokens = docs.map((doc) => tokenize(doc));
2256
+ if (queryTokens.length === 0) {
2257
+ return docs.map(() => 1);
2258
+ }
2259
+ const docLengths = docTokens.map((tokens) => tokens.length);
2260
+ const avgDocLen = docLengths.reduce((sum2, len) => sum2 + len, 0) / Math.max(1, docLengths.length);
2261
+ const uniqueQueryTerms = [...new Set(queryTokens)];
2262
+ const df = /* @__PURE__ */ new Map();
2263
+ for (const term of uniqueQueryTerms) {
2264
+ let count = 0;
2265
+ for (const tokens of docTokens) {
2266
+ if (tokens.includes(term)) count += 1;
2267
+ }
2268
+ df.set(term, count);
2269
+ }
2270
+ const n = docs.length;
2271
+ const idf = /* @__PURE__ */ new Map();
2272
+ for (const term of uniqueQueryTerms) {
2273
+ const freq = df.get(term) || 0;
2274
+ idf.set(term, Math.log(1 + (n - freq + 0.5) / (freq + 0.5)));
2275
+ }
2276
+ return docTokens.map((tokens, docIndex) => {
2277
+ if (tokens.length === 0) return 0;
2278
+ const termFreq = /* @__PURE__ */ new Map();
2279
+ for (const token of tokens) {
2280
+ termFreq.set(token, (termFreq.get(token) || 0) + 1);
2281
+ }
2282
+ const docLen = docLengths[docIndex];
2283
+ let score = 0;
2284
+ for (const term of uniqueQueryTerms) {
2285
+ const freq = termFreq.get(term) || 0;
2286
+ if (freq === 0) continue;
2287
+ const termIdf = idf.get(term) || 0;
2288
+ const numerator = freq * (k1 + 1);
2289
+ const denominator = freq + k1 * (1 - b + b * docLen / avgDocLen);
2290
+ score += termIdf * (numerator / denominator);
2291
+ }
2292
+ return score;
2293
+ });
2294
+ }
2295
+ function selectTopIndicesInOrder(scores, count) {
2296
+ 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);
2297
+ return ranked.sort((a, b) => a - b);
2298
+ }
2299
+ var CCRStore = class _CCRStore {
2300
+ constructor(options = {}) {
2301
+ this.entries = /* @__PURE__ */ new Map();
2302
+ this.defaultTtlMs = options.ttlMs ?? 30 * 60 * 1e3;
2303
+ this.maxEntries = options.maxEntries ?? 500;
2304
+ }
2305
+ /** Stores `value` and returns a short content hash that can be used to retrieve it later. */
2306
+ store(value, ttlMs) {
2307
+ const hash = _CCRStore.hashOf(value);
2308
+ this.entries.delete(hash);
2309
+ this.entries.set(hash, { value, storedAt: Date.now(), ttlMs: ttlMs ?? this.defaultTtlMs });
2310
+ this.evictIfNeeded();
2311
+ return hash;
2312
+ }
2313
+ /** Returns the original value for `hash`, or `undefined` if missing/expired. */
2314
+ retrieve(hash) {
2315
+ const entry = this.entries.get(hash);
2316
+ if (!entry) return void 0;
2317
+ if (Date.now() - entry.storedAt > entry.ttlMs) {
2318
+ this.entries.delete(hash);
2319
+ return void 0;
2320
+ }
2321
+ return entry.value;
2322
+ }
2323
+ has(hash) {
2324
+ return this.retrieve(hash) !== void 0;
2325
+ }
2326
+ get size() {
2327
+ return this.entries.size;
2328
+ }
2329
+ evictIfNeeded() {
2330
+ while (this.entries.size > this.maxEntries) {
2331
+ const oldestKey = this.entries.keys().next().value;
2332
+ if (oldestKey === void 0) break;
2333
+ this.entries.delete(oldestKey);
2334
+ }
2335
+ }
2336
+ static hashOf(value) {
2337
+ const serialized = typeof value === "string" ? value : JSON.stringify(value);
2338
+ return createHash("sha1").update(serialized).digest("hex").slice(0, 16);
2339
+ }
2340
+ };
2341
+ var DedupTracker = class {
2342
+ constructor() {
2343
+ this.seen = /* @__PURE__ */ new Map();
2344
+ }
2345
+ /**
2346
+ * Registers `content` under `executionId`/`toolName`. Returns the entry
2347
+ * that first produced this exact content, or `undefined` if this is the
2348
+ * first time it has been seen.
2349
+ */
2350
+ checkAndRegister(content, executionId, toolName) {
2351
+ const hash = createHash("sha1").update(content).digest("hex");
2352
+ const existing = this.seen.get(hash);
2353
+ if (!existing) {
2354
+ this.seen.set(hash, { executionId, toolName });
2355
+ }
2356
+ return existing;
2357
+ }
2358
+ };
2359
+
2360
+ // src/smart/contextPilot/cacheAligner.ts
2361
+ var PATTERNS = [
2362
+ { 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 },
2363
+ { 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 },
2364
+ { kind: "jwt", regex: /\beyJ[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\b/g },
2365
+ { 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 },
2366
+ { kind: "api_key", regex: /\b(?:sk|pk|ghp|gho|ghu|ghs)-[A-Za-z0-9]{10,}\b/g },
2367
+ { kind: "unix_timestamp", regex: /\b1\d{12}\b(?!\d)|\b1\d{9}\b(?!\d)/g }
2368
+ ];
2369
+ function detectVolatileContent(text, limit = 20) {
2370
+ if (!text) return [];
2371
+ const findings = [];
2372
+ for (const { kind, regex } of PATTERNS) {
2373
+ regex.lastIndex = 0;
2374
+ let match;
2375
+ while (findings.length < limit && (match = regex.exec(text)) !== null) {
2376
+ findings.push({ pattern: kind, match: match[0], index: match.index });
2377
+ if (regex.lastIndex === match.index) regex.lastIndex += 1;
2378
+ }
2379
+ }
2380
+ return findings;
2381
+ }
2382
+
2383
+ // src/smart/contextPilot/jsonCrusher.ts
2384
+ init_utilTokens();
2385
+
2386
+ // src/utils/content.ts
2387
+ function contentToString(content) {
2388
+ try {
2389
+ if (content == null) return "";
2390
+ if (typeof content === "string") return content;
2391
+ if (Array.isArray(content)) {
2392
+ return content.map((p) => {
2393
+ if (!p || typeof p !== "object") return String(p);
2394
+ if (p.type === "text") return String(p.text ?? "");
2395
+ if (p.type === "image_url") {
2396
+ const img = p.image_url;
2397
+ const url = typeof img === "string" ? img : img?.url;
2398
+ const detail = typeof img === "string" ? void 0 : img?.detail;
2399
+ return `[image:${url || "unknown"}${detail ? ` detail=${detail}` : ""}]`;
2400
+ }
2401
+ return JSON.stringify(p);
2402
+ }).join("\n");
2403
+ }
2404
+ return JSON.stringify(content);
2405
+ } catch {
2406
+ return String(content);
2407
+ }
2408
+ }
2409
+ function mergeContentsToString(contents) {
2410
+ return contents.map((c) => contentToString(c)).join("\n");
2411
+ }
2412
+ function safeStringify(value, pretty = false) {
2413
+ if (value == null) return "";
2414
+ if (typeof value === "string") return value;
2415
+ try {
2416
+ return JSON.stringify(value, null, pretty ? 2 : void 0) ?? String(value);
2417
+ } catch {
2418
+ return String(value);
2419
+ }
2420
+ }
2421
+ function extractMessageText2(message) {
2422
+ if (!message) return "";
2423
+ const content = message.content;
2424
+ if (typeof content === "string") return content;
2425
+ if (Array.isArray(content)) {
2426
+ return content.map((part) => typeof part === "string" ? part : part?.text ?? part?.content ?? "").join("");
2427
+ }
2428
+ return "";
2429
+ }
2430
+
2431
+ // src/smart/contextPilot/jsonCrusher.ts
2432
+ var CONTEXT_PILOT_JSON_MARKER_KEY = "__contextPilotDropped";
2433
+ function findCompressibleArray(output, minItems) {
2434
+ if (Array.isArray(output)) {
2435
+ return { array: output, wrap: (arr) => arr };
2436
+ }
2437
+ if (output && typeof output === "object") {
2438
+ let bestKey;
2439
+ let bestArray;
2440
+ for (const [key, value] of Object.entries(output)) {
2441
+ if (Array.isArray(value) && (!bestArray || value.length > bestArray.length)) {
2442
+ bestKey = key;
2443
+ bestArray = value;
2444
+ }
2445
+ }
2446
+ if (bestKey && bestArray && bestArray.length >= minItems) {
2447
+ const key = bestKey;
2448
+ return {
2449
+ array: bestArray,
2450
+ wrap: (arr) => ({ ...output, [key]: arr })
2451
+ };
2452
+ }
2453
+ }
2454
+ return null;
2455
+ }
2456
+ function notApplied(output) {
2457
+ const tokens = countApproxTokens(safeStringify(output));
2458
+ return { applied: false, compressorUsed: "none", output, originalTokens: tokens, compressedTokens: tokens };
2459
+ }
2460
+ function compressJsonOutput(output, query, config, ccrStore) {
2461
+ if (!config.enabled) return notApplied(output);
2462
+ const target = findCompressibleArray(output, config.minItems);
2463
+ if (!target || target.array.length < config.minItems) return notApplied(output);
2464
+ const { array, wrap } = target;
2465
+ const itemTexts = array.map((item) => safeStringify(item));
2466
+ const scores = scoreItemsByRelevance(itemTexts, query);
2467
+ const keepCount = Math.max(1, Math.min(array.length, Math.ceil(array.length * config.targetRatio)));
2468
+ const keepIndices = new Set(selectTopIndicesInOrder(scores, keepCount));
2469
+ const droppedCount = array.length - keepIndices.size;
2470
+ if (droppedCount <= 0) return notApplied(output);
2471
+ const originalTokens = countApproxTokens(safeStringify(output));
2472
+ const ccrHash = ccrStore.store(output);
2473
+ const keptItems = array.filter((_item, index) => keepIndices.has(index));
2474
+ const marker = {
2475
+ [CONTEXT_PILOT_JSON_MARKER_KEY]: droppedCount,
2476
+ 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.`
2477
+ };
2478
+ const compressedOutput = wrap([...keptItems, marker]);
2479
+ const compressedTokens = countApproxTokens(safeStringify(compressedOutput));
2480
+ if (compressedTokens >= originalTokens * 0.9) return notApplied(output);
2481
+ return {
2482
+ applied: true,
2483
+ compressorUsed: "jsonCrusher",
2484
+ output: compressedOutput,
2485
+ originalTokens,
2486
+ compressedTokens,
2487
+ droppedItems: droppedCount,
2488
+ ccrHash
2489
+ };
2490
+ }
2491
+
2492
+ // src/smart/contextPilot/textCrusher.ts
2493
+ init_utilTokens();
2494
+ function splitIntoSentences(text) {
2495
+ return text.split(/(?<=[.!?。!?\n])\s*/u).map((sentence) => sentence.trim()).filter(Boolean);
2496
+ }
2497
+ function normalizeForDedup(sentence) {
2498
+ return sentence.toLowerCase().replace(/\s+/g, " ").trim();
2499
+ }
2500
+ function notApplied2(text) {
2501
+ const tokens = countApproxTokens(text);
2502
+ return { applied: false, compressorUsed: "none", output: text, originalTokens: tokens, compressedTokens: tokens };
2503
+ }
2504
+ function compressTextOutput(text, query, config, ccrStore) {
2505
+ if (!config.enabled || text.length < config.minChars) return notApplied2(text);
2506
+ const rawSentences = splitIntoSentences(text);
2507
+ if (rawSentences.length < 6) return notApplied2(text);
2508
+ const seenNormalized = /* @__PURE__ */ new Set();
2509
+ const dedupedIndices = [];
2510
+ rawSentences.forEach((sentence, index) => {
2511
+ const key = normalizeForDedup(sentence);
2512
+ if (seenNormalized.has(key)) return;
2513
+ seenNormalized.add(key);
2514
+ dedupedIndices.push(index);
2515
+ });
2516
+ const relevanceScores = scoreItemsByRelevance(dedupedIndices.map((i) => rawSentences[i]), query);
2517
+ const recencyBoost = dedupedIndices.map((_value, position) => position / Math.max(1, dedupedIndices.length - 1));
2518
+ const combinedScores = relevanceScores.map((score, i) => score + recencyBoost[i] * 0.25);
2519
+ const keepCount = Math.max(3, Math.ceil(dedupedIndices.length * config.targetRatio));
2520
+ const keepPositions = new Set(selectTopIndicesInOrder(combinedScores, keepCount));
2521
+ const keptSentences = dedupedIndices.filter((_index, position) => keepPositions.has(position)).map((i) => rawSentences[i]);
2522
+ const droppedCount = rawSentences.length - keptSentences.length;
2523
+ if (droppedCount <= 0) return notApplied2(text);
2524
+ const originalTokens = countApproxTokens(text);
2525
+ const ccrHash = ccrStore.store(text);
2526
+ const compressedText = `${keptSentences.join(" ")}
2527
+ [ContextPilot: ${droppedCount} lower-relevance sentence(s) omitted. Use get_tool_response with executionId="${ccrHash}" to retrieve the full original text.]`;
2528
+ const compressedTokens = countApproxTokens(compressedText);
2529
+ if (compressedTokens >= originalTokens * 0.9) return notApplied2(text);
2530
+ return {
2531
+ applied: true,
2532
+ compressorUsed: "textCrusher",
2533
+ output: compressedText,
2534
+ originalTokens,
2535
+ compressedTokens,
2536
+ droppedItems: droppedCount,
2537
+ ccrHash
2538
+ };
2539
+ }
2540
+
2541
+ // src/smart/contextPilot/formatCompressors.ts
2542
+ init_utilTokens();
2543
+ function notApplied3(text) {
2544
+ const tokens = countApproxTokens(text);
2545
+ return { applied: false, compressorUsed: "none", output: text, originalTokens: tokens, compressedTokens: tokens };
2546
+ }
2547
+ function detectTextFormat(text) {
2548
+ const sample = text.slice(0, 2e3);
2549
+ if (/^diff --git |^---\s|^\+\+\+\s|^@@ -\d+/m.test(sample)) return "diff";
2550
+ if (/^[\w./-]+:\d+:/m.test(sample) || /^[\w./-]+-\d+-/m.test(sample)) return "search";
2551
+ if (/\b(ERROR|FAIL|FAILED|WARN|PASS|PASSED)\b/.test(sample) && text.split("\n").length > 15) return "log";
2552
+ return "text";
2553
+ }
2554
+ function compressDiffOutput(text, config, ccrStore) {
2555
+ if (!config.enabled) return notApplied3(text);
2556
+ const lines = text.split("\n");
2557
+ const kept = [];
2558
+ let contextRun = 0;
2559
+ let trimmedAny = false;
2560
+ for (const line of lines) {
2561
+ const isHeader = line.startsWith("diff --git") || line.startsWith("---") || line.startsWith("+++") || line.startsWith("@@");
2562
+ const isChange = line.startsWith("+") || line.startsWith("-");
2563
+ if (isHeader || isChange) {
2564
+ kept.push(line);
2565
+ contextRun = 0;
2566
+ continue;
2567
+ }
2568
+ if (contextRun < config.contextLines) {
2569
+ kept.push(line);
2570
+ contextRun += 1;
2571
+ } else {
2572
+ trimmedAny = true;
2573
+ }
2574
+ }
2575
+ if (!trimmedAny) return notApplied3(text);
2576
+ const originalTokens = countApproxTokens(text);
2577
+ const ccrHash = ccrStore.store(text);
2578
+ const compressedText = `${kept.join("\n")}
2579
+ [ContextPilot: unchanged context lines beyond ${config.contextLines} trimmed. Use get_tool_response with executionId="${ccrHash}" to retrieve the full diff.]`;
2580
+ const compressedTokens = countApproxTokens(compressedText);
2581
+ if (compressedTokens >= originalTokens * 0.9) return notApplied3(text);
2582
+ return { applied: true, compressorUsed: "diffCompressor", output: compressedText, originalTokens, compressedTokens, ccrHash };
2583
+ }
2584
+ var LOG_LEVEL_SCORE = [
2585
+ { regex: /\b(FAIL|FAILED|ERROR|FATAL|EXCEPTION|TRACEBACK)\b/i, score: 1 },
2586
+ { regex: /\b(WARN|WARNING)\b/i, score: 0.7 },
2587
+ { regex: /\b(PASS|PASSED|OK|SUCCESS)\b/i, score: 0.4 },
2588
+ { regex: /\bINFO\b/i, score: 0.3 },
2589
+ { regex: /\b(DEBUG|TRACE)\b/i, score: 0.1 }
2590
+ ];
2591
+ function scoreLogLine(line) {
2592
+ for (const { regex, score } of LOG_LEVEL_SCORE) {
2593
+ if (regex.test(line)) return score;
2594
+ }
2595
+ return 0.2;
2596
+ }
2597
+ function compressLogOutput(text, config, ccrStore) {
2598
+ if (!config.enabled) return notApplied3(text);
2599
+ const lines = text.split("\n").filter((line) => line.length > 0);
2600
+ if (lines.length <= config.maxLines) return notApplied3(text);
2601
+ const scored = lines.map((line, index) => ({ line, index, score: scoreLogLine(line) }));
2602
+ const mustKeep = /* @__PURE__ */ new Set([0, lines.length - 1]);
2603
+ 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);
2604
+ const keepIndices = /* @__PURE__ */ new Set([...mustKeep, ...ranked]);
2605
+ const droppedCount = lines.length - keepIndices.size;
2606
+ if (droppedCount <= 0) return notApplied3(text);
2607
+ const originalTokens = countApproxTokens(text);
2608
+ const ccrHash = ccrStore.store(text);
2609
+ const keptLines = lines.filter((_line, index) => keepIndices.has(index));
2610
+ const compressedText = `${keptLines.join("\n")}
2611
+ [ContextPilot: ${droppedCount} lower-priority log line(s) omitted (errors/warnings preserved). Use get_tool_response with executionId="${ccrHash}" to retrieve the full log.]`;
2612
+ const compressedTokens = countApproxTokens(compressedText);
2613
+ if (compressedTokens >= originalTokens * 0.9) return notApplied3(text);
2614
+ return { applied: true, compressorUsed: "logCompressor", output: compressedText, originalTokens, compressedTokens, droppedItems: droppedCount, ccrHash };
2615
+ }
2616
+ function compressSearchOutput(text, config, ccrStore) {
2617
+ if (!config.enabled) return notApplied3(text);
2618
+ const lines = text.split("\n").filter((line) => line.length > 0);
2619
+ if (lines.length <= config.maxMatches) return notApplied3(text);
2620
+ const perFileCount = /* @__PURE__ */ new Map();
2621
+ const perFileCap = Math.max(3, Math.ceil(config.maxMatches / 4));
2622
+ const kept = [];
2623
+ for (const line of lines) {
2624
+ if (kept.length >= config.maxMatches) break;
2625
+ const fileKey = line.split(/[:-]/)[0] || "unknown";
2626
+ const count = perFileCount.get(fileKey) || 0;
2627
+ if (count >= perFileCap) continue;
2628
+ perFileCount.set(fileKey, count + 1);
2629
+ kept.push(line);
2630
+ }
2631
+ const droppedCount = lines.length - kept.length;
2632
+ if (droppedCount <= 0) return notApplied3(text);
2633
+ const originalTokens = countApproxTokens(text);
2634
+ const ccrHash = ccrStore.store(text);
2635
+ const compressedText = `${kept.join("\n")}
2636
+ [ContextPilot: ${droppedCount} additional match(es) omitted. Use get_tool_response with executionId="${ccrHash}" to retrieve all matches.]`;
2637
+ const compressedTokens = countApproxTokens(compressedText);
2638
+ if (compressedTokens >= originalTokens * 0.9) return notApplied3(text);
2639
+ return { applied: true, compressorUsed: "searchCompressor", output: compressedText, originalTokens, compressedTokens, droppedItems: droppedCount, ccrHash };
2640
+ }
2641
+
2642
+ // src/smart/contextPilot/pipeline.ts
2643
+ init_utilTokens();
2644
+ function createContextPilotRuntime(config) {
2645
+ return {
2646
+ ccrStore: new CCRStore({ ttlMs: config.ccr.ttlMs, maxEntries: config.ccr.maxEntries }),
2647
+ dedupTracker: new DedupTracker()
2648
+ };
2649
+ }
2650
+ function extractLatestUserQuery(messages) {
2651
+ if (!Array.isArray(messages)) return "";
2652
+ for (let i = messages.length - 1; i >= 0; i -= 1) {
2653
+ const message = messages[i];
2654
+ if (message?.role !== "user") continue;
2655
+ if (typeof message.content === "string") return message.content;
2656
+ if (Array.isArray(message.content)) {
2657
+ return message.content.map((part) => typeof part?.text === "string" ? part.text : "").filter(Boolean).join(" ");
2658
+ }
2659
+ }
2660
+ return "";
2661
+ }
2662
+ function notApplied4(output) {
2663
+ const tokens = countApproxTokens(safeStringify(output));
2664
+ return { applied: false, compressorUsed: "none", output, originalTokens: tokens, compressedTokens: tokens };
2665
+ }
2666
+ function compressToolOutput(params) {
2667
+ const { toolName, output, query, executionId, config, runtime } = params;
2668
+ if (!config.enabled || config.excludeTools.includes(toolName)) return notApplied4(output);
2669
+ const ccrAvailable = config.ccr.enabled && config.ccr.maxEntries > 0;
2670
+ if (config.dedup.enabled) {
2671
+ const serialized = typeof output === "string" ? output : safeStringify(output);
2672
+ if (serialized.length >= config.dedup.minChars) {
2673
+ const duplicate = runtime.dedupTracker.checkAndRegister(serialized, executionId, toolName);
2674
+ if (duplicate) {
2675
+ const originalTokens = countApproxTokens(serialized);
2676
+ const pointer = `DUPLICATE_TOOL_RESPONSE [toolName=${toolName}]
2677
+ Identical to an earlier ${duplicate.toolName} result. Use get_tool_response with executionId="${duplicate.executionId}" to view it.`;
2678
+ return {
2679
+ applied: true,
2680
+ compressorUsed: "none",
2681
+ output: pointer,
2682
+ originalTokens,
2683
+ compressedTokens: countApproxTokens(pointer),
2684
+ duplicateOf: duplicate.executionId
2685
+ };
2686
+ }
2687
+ }
2688
+ }
2689
+ if (typeof output !== "string") {
2690
+ if (ccrAvailable && config.compression.json.enabled) {
2691
+ const result = compressJsonOutput(output, query, config.compression.json, runtime.ccrStore);
2692
+ if (result.applied) return result;
2693
+ }
2694
+ return notApplied4(output);
2695
+ }
2696
+ const format = detectTextFormat(output);
2697
+ if (ccrAvailable && format === "diff" && config.compression.diff.enabled) {
2698
+ const result = compressDiffOutput(output, config.compression.diff, runtime.ccrStore);
2699
+ if (result.applied) return result;
2700
+ } else if (ccrAvailable && format === "log" && config.compression.log.enabled) {
2701
+ const result = compressLogOutput(output, config.compression.log, runtime.ccrStore);
2702
+ if (result.applied) return result;
2703
+ } else if (ccrAvailable && format === "search" && config.compression.search.enabled) {
2704
+ const result = compressSearchOutput(output, config.compression.search, runtime.ccrStore);
2705
+ if (result.applied) return result;
2706
+ }
2707
+ if (ccrAvailable && config.compression.text.enabled) {
2708
+ const result = compressTextOutput(output, query, config.compression.text, runtime.ccrStore);
2709
+ if (result.applied) return result;
2710
+ }
2711
+ return notApplied4(output);
2712
+ }
2713
+
1976
2714
  // src/nodes/agentCore.ts
1977
2715
  function createAgentCoreNode(opts) {
1978
2716
  return async (state) => {
@@ -2072,6 +2810,42 @@ function createAgentCoreNode(opts) {
2072
2810
  const streamingEnabled = Boolean(state.ctx?.__streaming);
2073
2811
  const cancellationToken = state.ctx?.__cancellationToken;
2074
2812
  const abortSignal = state.ctx?.__abortSignal;
2813
+ const resolvedForCachePilot = getResolvedSmartConfig(opts, runtime);
2814
+ if (resolvedForCachePilot.contextPilot.enabled && resolvedForCachePilot.contextPilot.cacheAlignment.enabled) {
2815
+ const ctxForCacheWarning = state.ctx = state.ctx || {};
2816
+ if (!ctxForCacheWarning.__contextPilotCacheWarned) {
2817
+ const systemMessages = (state.messages || []).filter((m) => m?.role === "system");
2818
+ const systemText = systemMessages.map((m) => typeof m.content === "string" ? m.content : "").join("\n");
2819
+ const findings = detectVolatileContent(systemText);
2820
+ if (findings.length > 0) {
2821
+ ctxForCacheWarning.__contextPilotCacheWarned = true;
2822
+ if (resolvedForCachePilot.contextPilot.cacheAlignment.warnOnVolatilePrompt) {
2823
+ const patternCounts = findings.reduce((acc, finding) => {
2824
+ acc[finding.pattern] = (acc[finding.pattern] || 0) + 1;
2825
+ return acc;
2826
+ }, {});
2827
+ onEvent?.({
2828
+ type: "metadata",
2829
+ reason: "context_pilot_cache_alignment",
2830
+ message: "Volatile content detected in system prompt; this may defeat provider-side prompt caching.",
2831
+ patternCounts
2832
+ });
2833
+ recordTraceEvent(traceSession, {
2834
+ type: "metadata",
2835
+ label: "ContextPilot: volatile system prompt content",
2836
+ actor: { scope: "agent", name: actorName, role: "agent" },
2837
+ sections: [
2838
+ {
2839
+ kind: "metadata",
2840
+ label: "Volatile content findings",
2841
+ data: { patternCounts, totalFindings: findings.length }
2842
+ }
2843
+ ]
2844
+ });
2845
+ }
2846
+ }
2847
+ }
2848
+ }
2075
2849
  const responseFormat = runtime.responseFormat;
2076
2850
  const reasoningForCall = state.ctx?.__reasoning;
2077
2851
  const reasoningInvokeOpts = reasoningForCall ? { reasoning: reasoningForCall } : void 0;
@@ -2166,68 +2940,23 @@ function createAgentCoreNode(opts) {
2166
2940
  const id = `${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
2167
2941
  const turn = usageState.perRequest.length + 1;
2168
2942
  const timestamp = (/* @__PURE__ */ new Date()).toISOString();
2169
- const cachedInputTok = normalized.prompt_tokens_details?.cached_tokens;
2170
- usageState.perRequest.push({ id, modelName, usage: normalized, timestamp, turn, cachedInput: cachedInputTok });
2171
- const inputTok = normalized.prompt_tokens;
2172
- const outputTok = normalized.completion_tokens;
2173
- const totalTok = normalized.total_tokens;
2174
- const key = modelName;
2175
- const agg = usageState.totals[key] || { input: 0, output: 0, total: 0, cachedInput: 0 };
2176
- usageState.totals[key] = {
2177
- input: agg.input + (Number(inputTok) || 0),
2178
- output: agg.output + (Number(outputTok) || 0),
2179
- total: agg.total + (Number(totalTok) || 0),
2180
- cachedInput: agg.cachedInput + (Number(cachedInputTok) || 0)
2181
- };
2182
- state.usage = usageState;
2183
- }
2184
- return { messages: messagesWithResponse, usage: state.usage };
2185
- };
2186
- }
2187
-
2188
- // src/utils/content.ts
2189
- function contentToString(content) {
2190
- try {
2191
- if (content == null) return "";
2192
- if (typeof content === "string") return content;
2193
- if (Array.isArray(content)) {
2194
- return content.map((p) => {
2195
- if (!p || typeof p !== "object") return String(p);
2196
- if (p.type === "text") return String(p.text ?? "");
2197
- if (p.type === "image_url") {
2198
- const img = p.image_url;
2199
- const url = typeof img === "string" ? img : img?.url;
2200
- const detail = typeof img === "string" ? void 0 : img?.detail;
2201
- return `[image:${url || "unknown"}${detail ? ` detail=${detail}` : ""}]`;
2202
- }
2203
- return JSON.stringify(p);
2204
- }).join("\n");
2943
+ const cachedInputTok = normalized.prompt_tokens_details?.cached_tokens;
2944
+ usageState.perRequest.push({ id, modelName, usage: normalized, timestamp, turn, cachedInput: cachedInputTok });
2945
+ const inputTok = normalized.prompt_tokens;
2946
+ const outputTok = normalized.completion_tokens;
2947
+ const totalTok = normalized.total_tokens;
2948
+ const key = modelName;
2949
+ const agg = usageState.totals[key] || { input: 0, output: 0, total: 0, cachedInput: 0 };
2950
+ usageState.totals[key] = {
2951
+ input: agg.input + (Number(inputTok) || 0),
2952
+ output: agg.output + (Number(outputTok) || 0),
2953
+ total: agg.total + (Number(totalTok) || 0),
2954
+ cachedInput: agg.cachedInput + (Number(cachedInputTok) || 0)
2955
+ };
2956
+ state.usage = usageState;
2205
2957
  }
2206
- return JSON.stringify(content);
2207
- } catch {
2208
- return String(content);
2209
- }
2210
- }
2211
- function mergeContentsToString(contents) {
2212
- return contents.map((c) => contentToString(c)).join("\n");
2213
- }
2214
- function safeStringify(value, pretty = false) {
2215
- if (value == null) return "";
2216
- if (typeof value === "string") return value;
2217
- try {
2218
- return JSON.stringify(value, null, pretty ? 2 : void 0) ?? String(value);
2219
- } catch {
2220
- return String(value);
2221
- }
2222
- }
2223
- function extractMessageText(message) {
2224
- if (!message) return "";
2225
- const content = message.content;
2226
- if (typeof content === "string") return content;
2227
- if (Array.isArray(content)) {
2228
- return content.map((part) => typeof part === "string" ? part : part?.text ?? part?.content ?? "").join("");
2229
- }
2230
- return "";
2958
+ return { messages: messagesWithResponse, usage: state.usage };
2959
+ };
2231
2960
  }
2232
2961
 
2233
2962
  // src/utils/traceSections.ts
@@ -2268,217 +2997,6 @@ function extractToolItems(output) {
2268
2997
  });
2269
2998
  }
2270
2999
 
2271
- // src/smart/runtimeConfig.ts
2272
- var DEFAULT_CRITICAL_TOOLS = ["response", "manage_todo_list", "get_tool_response"];
2273
- var BASE_DEFAULTS = {
2274
- limits: { maxToolCalls: 20, maxParallelTools: 5, maxContextTokens: 96e3, maxTotalOutputTokens: 0, maxCostUsd: 0, maxWallClockMs: 0 },
2275
- summarization: {
2276
- enable: true,
2277
- maxTokens: 96e3,
2278
- summaryTriggerTokens: 72e3,
2279
- summaryPromptMaxTokens: 12e3,
2280
- summaryCompressionRatioTarget: 0.45,
2281
- summaryMode: "incremental",
2282
- promptTemplate: "",
2283
- toolFreeCall: true,
2284
- integrityCheck: true
2285
- },
2286
- context: {
2287
- policy: "hybrid",
2288
- lastTurnsToKeep: 16,
2289
- toolResponsePolicy: "summarize_archive",
2290
- budget: {
2291
- systemReserveTokens: 2e3,
2292
- goalsReserveTokens: 2e3,
2293
- recentTurnsReserveTokens: 18e3,
2294
- toolResponseReserveTokens: 9e3
2295
- }
2296
- },
2297
- planning: {
2298
- mode: "off",
2299
- replanPolicy: "on_failure",
2300
- everyNSteps: 0
2301
- },
2302
- memory: {
2303
- provider: "inMemory",
2304
- scope: "session",
2305
- writePolicy: "auto_important",
2306
- readPolicy: "hybrid"
2307
- },
2308
- delegation: {
2309
- mode: "role_based",
2310
- maxDelegationDepth: 2,
2311
- maxChildCalls: 6,
2312
- maxParallelChild: 3,
2313
- childContextPolicy: "scoped",
2314
- requireJsonOutputContract: true
2315
- },
2316
- toolResponses: {
2317
- maxToolResponseChars: 32e3,
2318
- maxToolResponseTokens: 8e3,
2319
- defaultPolicy: "summarize_archive",
2320
- toolResponseRetentionByTool: {},
2321
- criticalTools: [...DEFAULT_CRITICAL_TOOLS],
2322
- schemaValidation: "strict"
2323
- }
2324
- };
2325
- function buildProfile(overrides) {
2326
- return {
2327
- limits: { ...BASE_DEFAULTS.limits, ...overrides.limits },
2328
- summarization: { ...BASE_DEFAULTS.summarization, ...overrides.summarization },
2329
- context: {
2330
- ...BASE_DEFAULTS.context,
2331
- ...overrides.context,
2332
- budget: { ...BASE_DEFAULTS.context.budget, ...overrides.context?.budget }
2333
- },
2334
- planning: { ...BASE_DEFAULTS.planning, ...overrides.planning },
2335
- memory: { ...BASE_DEFAULTS.memory, ...overrides.memory },
2336
- delegation: { ...BASE_DEFAULTS.delegation, ...overrides.delegation },
2337
- toolResponses: {
2338
- ...BASE_DEFAULTS.toolResponses,
2339
- ...overrides.toolResponses,
2340
- criticalTools: overrides.toolResponses?.criticalTools ?? [...DEFAULT_CRITICAL_TOOLS],
2341
- toolResponseRetentionByTool: overrides.toolResponses?.toolResponseRetentionByTool ?? {}
2342
- }
2343
- };
2344
- }
2345
- var DEFAULT_PROFILE_CONFIGS = {
2346
- fast: buildProfile({
2347
- limits: { maxToolCalls: 8, maxParallelTools: 3, maxContextTokens: 32e3 },
2348
- summarization: {
2349
- maxTokens: 32e3,
2350
- summaryTriggerTokens: 24e3,
2351
- summaryPromptMaxTokens: 6e3,
2352
- summaryCompressionRatioTarget: 0.5
2353
- },
2354
- context: {
2355
- lastTurnsToKeep: 8,
2356
- toolResponsePolicy: "keep_structured",
2357
- budget: { systemReserveTokens: 1500, goalsReserveTokens: 1200, recentTurnsReserveTokens: 6e3, toolResponseReserveTokens: 3500 }
2358
- },
2359
- memory: { readPolicy: "recent_only" },
2360
- delegation: { mode: "off", maxDelegationDepth: 1, maxChildCalls: 2, maxParallelChild: 1, childContextPolicy: "minimal" },
2361
- toolResponses: { maxToolResponseChars: 16e3, maxToolResponseTokens: 4e3 }
2362
- }),
2363
- balanced: buildProfile({}),
2364
- deep: buildProfile({
2365
- limits: { maxToolCalls: 40, maxParallelTools: 8, maxContextTokens: 2e5 },
2366
- summarization: {
2367
- maxTokens: 2e5,
2368
- summaryTriggerTokens: 15e4,
2369
- summaryPromptMaxTokens: 16e3,
2370
- summaryCompressionRatioTarget: 0.4
2371
- },
2372
- context: {
2373
- lastTurnsToKeep: 30,
2374
- budget: { systemReserveTokens: 2500, goalsReserveTokens: 2500, recentTurnsReserveTokens: 36e3, toolResponseReserveTokens: 18e3 }
2375
- },
2376
- memory: { scope: "workspace" },
2377
- delegation: { maxDelegationDepth: 3, maxChildCalls: 10, maxParallelChild: 4 },
2378
- toolResponses: { maxToolResponseChars: 64e3, maxToolResponseTokens: 16e3 }
2379
- }),
2380
- research: buildProfile({
2381
- limits: { maxToolCalls: 80, maxParallelTools: 10, maxContextTokens: 4e5 },
2382
- summarization: {
2383
- maxTokens: 4e5,
2384
- summaryTriggerTokens: 3e5,
2385
- summaryPromptMaxTokens: 24e3,
2386
- summaryCompressionRatioTarget: 0.35
2387
- },
2388
- context: {
2389
- lastTurnsToKeep: 60,
2390
- budget: { systemReserveTokens: 3e3, goalsReserveTokens: 3e3, recentTurnsReserveTokens: 72e3, toolResponseReserveTokens: 32e3 }
2391
- },
2392
- memory: { scope: "workspace" },
2393
- delegation: { mode: "automatic", maxDelegationDepth: 4, maxChildCalls: 16, maxParallelChild: 6, childContextPolicy: "full" },
2394
- toolResponses: { maxToolResponseChars: 96e3, maxToolResponseTokens: 24e3 }
2395
- })
2396
- };
2397
- function mergeLimits(base, override) {
2398
- return {
2399
- maxToolCalls: override?.maxToolCalls ?? base.maxToolCalls,
2400
- maxParallelTools: override?.maxParallelTools ?? base.maxParallelTools,
2401
- maxContextTokens: override?.maxContextTokens ?? base.maxContextTokens,
2402
- maxTotalOutputTokens: override?.maxTotalOutputTokens ?? base.maxTotalOutputTokens ?? 0,
2403
- maxCostUsd: override?.maxCostUsd ?? base.maxCostUsd ?? 0,
2404
- maxWallClockMs: override?.maxWallClockMs ?? base.maxWallClockMs ?? 0
2405
- };
2406
- }
2407
- function resolveBaseProfile(opts, runtimeProfile) {
2408
- if (opts.customProfile?.extends) return opts.customProfile.extends;
2409
- if (runtimeProfile !== "custom") return runtimeProfile;
2410
- return "balanced";
2411
- }
2412
- function normalizeSmartAgentOptions(opts) {
2413
- const runtimeProfile = opts.runtimeProfile ?? (opts.customProfile ? "custom" : "balanced");
2414
- const baseProfile = resolveBaseProfile(opts, runtimeProfile);
2415
- const preset = DEFAULT_PROFILE_CONFIGS[baseProfile];
2416
- const customProfile = opts.customProfile || {};
2417
- const useTodoList = opts.useTodoList === true;
2418
- const summarizationDisabled = opts.summarization === false;
2419
- const summarizationOverride = typeof opts.summarization === "object" ? opts.summarization : {};
2420
- const planningMode = opts.planning?.mode ?? customProfile.planning?.mode ?? (useTodoList ? "todo" : preset.planning.mode);
2421
- const memoryStore = opts.memory?.store ?? customProfile.memory?.store;
2422
- const contextToolResponsePolicy = opts.context?.toolResponsePolicy ?? customProfile.context?.toolResponsePolicy ?? preset.context.toolResponsePolicy;
2423
- return {
2424
- runtimeProfile,
2425
- baseProfile,
2426
- limits: mergeLimits(mergeLimits(preset.limits, customProfile.limits), opts.limits),
2427
- summarization: {
2428
- ...preset.summarization,
2429
- ...customProfile.summarization || {},
2430
- ...summarizationOverride,
2431
- enable: summarizationDisabled ? false : summarizationOverride.enable ?? customProfile.summarization?.enable ?? preset.summarization.enable,
2432
- maxTokens: summarizationOverride.maxTokens ?? opts.limits?.maxContextTokens ?? customProfile.summarization?.maxTokens ?? preset.summarization.maxTokens,
2433
- summaryTriggerTokens: summarizationOverride.summaryTriggerTokens ?? summarizationOverride.maxTokens ?? opts.limits?.maxContextTokens ?? customProfile.summarization?.summaryTriggerTokens ?? customProfile.summarization?.maxTokens ?? preset.summarization.summaryTriggerTokens,
2434
- promptTemplate: summarizationOverride.promptTemplate ?? customProfile.summarization?.promptTemplate ?? preset.summarization.promptTemplate
2435
- },
2436
- context: {
2437
- ...preset.context,
2438
- ...customProfile.context || {},
2439
- ...opts.context || {},
2440
- budget: {
2441
- ...preset.context.budget,
2442
- ...customProfile.context?.budget || {},
2443
- ...opts.context?.budget || {}
2444
- },
2445
- toolResponsePolicy: contextToolResponsePolicy
2446
- },
2447
- planning: {
2448
- ...preset.planning,
2449
- ...customProfile.planning || {},
2450
- ...opts.planning || {},
2451
- mode: planningMode
2452
- },
2453
- memory: {
2454
- ...preset.memory,
2455
- ...customProfile.memory || {},
2456
- ...opts.memory || {},
2457
- store: memoryStore
2458
- },
2459
- delegation: {
2460
- ...preset.delegation,
2461
- ...customProfile.delegation || {},
2462
- ...opts.delegation || {}
2463
- },
2464
- toolResponses: {
2465
- ...preset.toolResponses,
2466
- ...customProfile.toolResponses || {},
2467
- ...opts.toolResponses || {},
2468
- defaultPolicy: opts.toolResponses?.defaultPolicy ?? customProfile.toolResponses?.defaultPolicy ?? contextToolResponsePolicy,
2469
- toolResponseRetentionByTool: {
2470
- ...preset.toolResponses.toolResponseRetentionByTool,
2471
- ...customProfile.toolResponses?.toolResponseRetentionByTool || {},
2472
- ...opts.toolResponses?.toolResponseRetentionByTool || {}
2473
- },
2474
- criticalTools: opts.toolResponses?.criticalTools ?? customProfile.toolResponses?.criticalTools ?? preset.toolResponses.criticalTools
2475
- }
2476
- };
2477
- }
2478
- function getResolvedSmartConfig(opts, runtime) {
2479
- return runtime?.smart || normalizeSmartAgentOptions(opts);
2480
- }
2481
-
2482
3000
  // src/smart/toolResponses.ts
2483
3001
  init_utilTokens();
2484
3002
  function summarizeObject(value) {
@@ -2720,6 +3238,23 @@ function createToolsNode(initialTools, opts) {
2720
3238
  outputSchema: opts?.outputSchema
2721
3239
  };
2722
3240
  const resolved = getResolvedSmartConfig(opts || {}, runtime);
3241
+ const contextPilotRuntime = state.ctx?.__contextPilot;
3242
+ const contextPilotQuery = contextPilotRuntime ? extractLatestUserQuery(state.messages) : "";
3243
+ const maybeCompressToolOutput = (toolNameForCompression, rawValue, executionIdForCompression) => {
3244
+ if (!contextPilotRuntime || !resolved.contextPilot.enabled) return { output: rawValue };
3245
+ if (resolved.toolResponses.criticalTools.includes(toolNameForCompression)) return { output: rawValue };
3246
+ const result = compressToolOutput({
3247
+ toolName: toolNameForCompression,
3248
+ output: rawValue,
3249
+ query: contextPilotQuery,
3250
+ executionId: executionIdForCompression,
3251
+ config: resolved.contextPilot,
3252
+ runtime: contextPilotRuntime
3253
+ });
3254
+ if (!result.applied) return { output: rawValue };
3255
+ const { output: compressedValue, ...stats } = result;
3256
+ return { output: compressedValue, stats };
3257
+ };
2723
3258
  const activeTools = runtime.tools;
2724
3259
  const toolByName = /* @__PURE__ */ new Map();
2725
3260
  for (const tool of activeTools) toolByName.set(tool.name, tool);
@@ -2957,12 +3492,13 @@ function createToolsNode(initialTools, opts) {
2957
3492
  try {
2958
3493
  if (cachedHit !== void 0) {
2959
3494
  const executionId2 = nanoid();
2960
- const responsePolicy2 = applyToolResponseHardCap(toolName, cachedHit, executionId2, resolved);
3495
+ const { output: compressedCachedHit, stats: cachedContextPilotStats } = maybeCompressToolOutput(toolName, cachedHit, executionId2);
3496
+ const responsePolicy2 = applyToolResponseHardCap(toolName, compressedCachedHit, executionId2, resolved);
2961
3497
  toolHistory.push({
2962
3498
  executionId: executionId2,
2963
3499
  toolName,
2964
3500
  args,
2965
- output: cachedHit,
3501
+ output: compressedCachedHit,
2966
3502
  rawOutput: cachedHit,
2967
3503
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
2968
3504
  tool_call_id: tc.id,
@@ -2971,7 +3507,8 @@ function createToolsNode(initialTools, opts) {
2971
3507
  classification: responsePolicy2.classification,
2972
3508
  retentionPolicy: "keep_full",
2973
3509
  fromCache: true,
2974
- status: "success"
3510
+ status: "success",
3511
+ contextPilot: cachedContextPilotStats
2975
3512
  });
2976
3513
  push({ role: "tool", content: responsePolicy2.content, tool_call_id: tc.id || `${tc.name}_${toolCount}`, name: tc.name });
2977
3514
  onEvent?.({ type: "tool_call", phase: "success", name: toolName, id: tc.id, args, result: cachedHit, durationMs: 0 });
@@ -3004,7 +3541,8 @@ function createToolsNode(initialTools, opts) {
3004
3541
  retentionPolicy: "keep_full",
3005
3542
  originalTokenCount: responsePolicy2.tokenCount,
3006
3543
  truncated: responsePolicy2.truncated,
3007
- fromCache: true
3544
+ fromCache: true,
3545
+ contextPilot: cachedContextPilotStats
3008
3546
  }
3009
3547
  });
3010
3548
  toolCount += 1;
@@ -3109,13 +3647,14 @@ function createToolsNode(initialTools, opts) {
3109
3647
  state.ctx.__structuredOutputParsed = output.data;
3110
3648
  state.ctx.__finalizedDueToStructuredOutput = true;
3111
3649
  }
3112
- const responsePolicy = applyToolResponseHardCap(toolName, output, executionId, resolved);
3650
+ const { output: compressedOutput, stats: contextPilotStats } = maybeCompressToolOutput(toolName, output, executionId);
3651
+ const responsePolicy = applyToolResponseHardCap(toolName, compressedOutput, executionId, resolved);
3113
3652
  const timestamp = (/* @__PURE__ */ new Date()).toISOString();
3114
3653
  toolHistory.push({
3115
3654
  executionId,
3116
3655
  toolName,
3117
3656
  args,
3118
- output,
3657
+ output: compressedOutput,
3119
3658
  rawOutput: output,
3120
3659
  timestamp,
3121
3660
  tool_call_id: tc.id,
@@ -3125,7 +3664,8 @@ function createToolsNode(initialTools, opts) {
3125
3664
  retentionPolicy: "keep_full",
3126
3665
  summary: void 0,
3127
3666
  archiveId: void 0,
3128
- status: "success"
3667
+ status: "success",
3668
+ contextPilot: contextPilotStats
3129
3669
  });
3130
3670
  push({ role: "tool", content: responsePolicy.content, tool_call_id: tc.id || `${tc.name}_${toolCount}`, name: tc.name });
3131
3671
  onEvent?.({ type: "tool_call", phase: "success", name: toolName, id: tc.id, args, result: output, durationMs });
@@ -3163,7 +3703,8 @@ function createToolsNode(initialTools, opts) {
3163
3703
  classification: responsePolicy.classification,
3164
3704
  retentionPolicy: "keep_full",
3165
3705
  originalTokenCount: responsePolicy.tokenCount,
3166
- truncated: responsePolicy.truncated
3706
+ truncated: responsePolicy.truncated,
3707
+ contextPilot: contextPilotStats
3167
3708
  }
3168
3709
  });
3169
3710
  toolCount += 1;
@@ -3802,7 +4343,8 @@ var DISALLOWED_CTX_KEYS = /* @__PURE__ */ new Set([
3802
4343
  "__traceSession",
3803
4344
  "__paused",
3804
4345
  "__cancellationToken",
3805
- "__abortSignal"
4346
+ "__abortSignal",
4347
+ "__contextPilot"
3806
4348
  ]);
3807
4349
  var clone = (value) => {
3808
4350
  if (typeof globalThis.structuredClone === "function") {
@@ -4753,7 +5295,7 @@ function createAgent(opts) {
4753
5295
  if (toolCalls.length === 0) {
4754
5296
  if (soManager && !state.ctx?.__finalizedDueToStructuredOutput && !state.ctx?.__structuredOutputForceFinalize) {
4755
5297
  if (soManager.strategy.kind === "native") {
4756
- const assistantText = extractMessageText(lastMsg);
5298
+ const assistantText = extractMessageText2(lastMsg);
4757
5299
  if (assistantText) {
4758
5300
  const parsed = soManager.parseFromContent(assistantText);
4759
5301
  if (parsed.success) {
@@ -4806,7 +5348,7 @@ function createAgent(opts) {
4806
5348
  if (soManager && !state.ctx?.__finalizedDueToStructuredOutput) {
4807
5349
  const lastForParse = state.messages[state.messages.length - 1];
4808
5350
  if (lastForParse?.role === "assistant") {
4809
- const assistantText = extractMessageText(lastForParse);
5351
+ const assistantText = extractMessageText2(lastForParse);
4810
5352
  if (assistantText) {
4811
5353
  const parsed = soManager.parseFromContent(assistantText);
4812
5354
  if (parsed.success) {
@@ -4915,6 +5457,10 @@ function createAgent(opts) {
4915
5457
  if (config?.timeoutMs && config.timeoutMs > 0) {
4916
5458
  ctx.__deadline = Date.now() + config.timeoutMs;
4917
5459
  }
5460
+ if (!ctx.__contextPilot) {
5461
+ const resolvedForContextPilot = getResolvedSmartConfig(opts, runtime);
5462
+ ctx.__contextPilot = createContextPilotRuntime(resolvedForContextPilot.contextPilot);
5463
+ }
4918
5464
  const runtimeWithInvokeLimits = config?.limits ? { ...runtime, limits: { ...runtime.limits || {}, ...config.limits } } : runtime;
4919
5465
  const initial = {
4920
5466
  messages: input.messages || [],
@@ -4959,7 +5505,7 @@ function createAgent(opts) {
4959
5505
  const isTransientSummarizationExit = !!res.ctx?.__needsSummarization;
4960
5506
  const finalAssistantMsg = isTransientSummarizationExit ? void 0 : getLastAssistantMessage(res.messages);
4961
5507
  const finalIsSyntheticSummary = !isTransientSummarizationExit && finalAssistantMsg && isSyntheticSummaryMessage(finalAssistantMsg);
4962
- const content = isTransientSummarizationExit || finalIsSyntheticSummary ? "" : extractMessageText(finalAssistantMsg);
5508
+ const content = isTransientSummarizationExit || finalIsSyntheticSummary ? "" : extractMessageText2(finalAssistantMsg);
4963
5509
  let parsed = void 0;
4964
5510
  let outputError = void 0;
4965
5511
  if (soManager) {
@@ -5268,7 +5814,7 @@ function renderMemoryBlock(facts) {
5268
5814
  function clampToBudget(messages, maxContextTokens) {
5269
5815
  let working = [...messages];
5270
5816
  while (working.length > 2) {
5271
- const tokenCount = countApproxTokens(working.map(extractMessageText).join("\n"));
5817
+ const tokenCount = countApproxTokens(working.map(extractMessageText2).join("\n"));
5272
5818
  if (tokenCount <= maxContextTokens) return working;
5273
5819
  const firstNonSystem = working.findIndex((message, index) => !(index === 0 && message.role === "system"));
5274
5820
  if (firstNonSystem < 0) break;
@@ -6141,6 +6687,13 @@ function createGetToolResponseTool(stateRef) {
6141
6687
  if (execution) {
6142
6688
  return execution.rawOutput || execution.output;
6143
6689
  }
6690
+ const ccrStore = stateRef.ctx?.__contextPilot?.ccrStore;
6691
+ if (ccrStore && typeof ccrStore.retrieve === "function") {
6692
+ const recovered = ccrStore.retrieve(executionId);
6693
+ if (recovered !== void 0) {
6694
+ return recovered;
6695
+ }
6696
+ }
6144
6697
  return "Execution not found. Please check the executionId.";
6145
6698
  }
6146
6699
  });
@@ -7072,7 +7625,7 @@ function createSmartAgent(opts) {
7072
7625
  ].join("\n");
7073
7626
  function latestUserPrompt(messages) {
7074
7627
  const latest = [...messages].reverse().find((message) => message.role === "user");
7075
- return latest ? extractMessageText(latest) : "";
7628
+ return latest ? extractMessageText2(latest) : "";
7076
7629
  }
7077
7630
  async function syncMemory(state) {
7078
7631
  const query = latestUserPrompt(state.messages || []);
@@ -10175,6 +10728,6 @@ function createProvider(config) {
10175
10728
  }
10176
10729
  }
10177
10730
 
10178
- export { AnthropicProvider, AzureProvider, BaseProvider, BedrockProvider, DEFAULT_PROFILE_CONFIGS, DEFAULT_SKILL_POLICY, DEFAULT_SUBAGENT_POLICY, DEFAULT_SUBAGENT_TOOL_NAMES, GuardrailPhase, InMemoryMemoryStore, NativeJsonSchemaStrategy, OpenAICompatibleProvider, OpenAIProvider, ProviderError, SMALL_TIER_SKILL_POLICY, StructuredOutputManager, ToolBasedStrategy, VertexProvider, agentVerdictRule, appendBoundTools, buildSkillHeaderBlock, buildSubagentCatalogBlock, buildSystemPrompt, canOpenSkill, canSpawn, captureSnapshot, codePresenceRule, cognipeerSink, composeToolSets, countApproxTokens, countMessagesTokens, createAgent, createAgentNode, createAskUserQuestionTool, createBindSkillToolsTool, createCodeGuardrail, createContextSummarizeNode, createContextTools, createDelegateTool, createGetToolResponseTool, createGuardrail, createJsonGuardrail, createManageTodoTool, createOpenSkillTool, createParallelTool, createProvider, createRegexGuardrail, createResolverNode, createSkillRegistryRef, createSkillTools, createSmartAgent, createSpawnTool, createSubagentRegistryRef, createSubagentTools, createTool, createToolLimitFinalizeNode, createToolsNode, customCallbackRule, customSink, dedupeToolsByName, defaultTokenCounter, emptyUsage, evaluateGuardrails, fileSink, findSubagent, formatZodError, fromLangchainModel, fromLangchainTools, fromNativeProvider, generateSpanId, generateTraceId, getModelCapabilities, getNestedValue, getResolvedSmartConfig, getTokenCounter, hasToolResponseRecoveryReference, httpSink, isSmartModel, jsonSchemaRule, loadSkillsFromDisk, normalizeSmartAgentOptions, otlpSink, parseSkillFrontmatter, readMemoryFacts, regexRule, resolveAvailableSkills, resolveAvailableSubagents, resolveMemoryStore, resolveReasoning, resolveStrategy, resolveSubagentTools, resolveToolApprovalState, resolveUserQuestionState, restoreSnapshot, runSmartAgentEvalHarness, seedChildMessages, setTokenCounter, startStreamingSession, traceSessionToOtlp, validateReasoningConfig, withTools, withinDepth, writeSummaryFactsToMemory };
10731
+ export { AnthropicProvider, AzureProvider, BaseProvider, BedrockProvider, CCRStore, CONTEXT_PILOT_JSON_MARKER_KEY, DEFAULT_PROFILE_CONFIGS, DEFAULT_SKILL_POLICY, DEFAULT_SUBAGENT_POLICY, DEFAULT_SUBAGENT_TOOL_NAMES, DedupTracker, GuardrailPhase, InMemoryMemoryStore, NativeJsonSchemaStrategy, OpenAICompatibleProvider, OpenAIProvider, ProviderError, SMALL_TIER_SKILL_POLICY, StructuredOutputManager, ToolBasedStrategy, VertexProvider, agentVerdictRule, appendBoundTools, buildSkillHeaderBlock, buildSubagentCatalogBlock, buildSystemPrompt, canOpenSkill, canSpawn, captureSnapshot, codePresenceRule, cognipeerSink, composeToolSets, compressDiffOutput, compressJsonOutput, compressLogOutput, compressSearchOutput, compressTextOutput, compressToolOutput, countApproxTokens, countMessagesTokens, createAgent, createAgentNode, createAskUserQuestionTool, createBindSkillToolsTool, createCodeGuardrail, createContextPilotRuntime, createContextSummarizeNode, createContextTools, createDelegateTool, createGetToolResponseTool, createGuardrail, createJsonGuardrail, createManageTodoTool, createOpenSkillTool, createParallelTool, createProvider, createRegexGuardrail, createResolverNode, createSkillRegistryRef, createSkillTools, createSmartAgent, createSpawnTool, createSubagentRegistryRef, createSubagentTools, createTool, createToolLimitFinalizeNode, createToolsNode, customCallbackRule, customSink, dedupeToolsByName, defaultTokenCounter, detectTextFormat, detectVolatileContent, emptyUsage, evaluateGuardrails, extractLatestUserQuery, fileSink, findSubagent, formatZodError, fromLangchainModel, fromLangchainTools, fromNativeProvider, generateSpanId, generateTraceId, getModelCapabilities, getNestedValue, getResolvedSmartConfig, getTokenCounter, hasToolResponseRecoveryReference, httpSink, isSmartModel, jsonSchemaRule, loadSkillsFromDisk, normalizeSmartAgentOptions, otlpSink, parseSkillFrontmatter, readMemoryFacts, regexRule, resolveAvailableSkills, resolveAvailableSubagents, resolveMemoryStore, resolveReasoning, resolveStrategy, resolveSubagentTools, resolveToolApprovalState, resolveUserQuestionState, restoreSnapshot, runSmartAgentEvalHarness, scoreItemsByRelevance, seedChildMessages, selectTopIndicesInOrder, setTokenCounter, startStreamingSession, tokenize, traceSessionToOtlp, validateReasoningConfig, withTools, withinDepth, writeSummaryFactsToMemory };
10179
10732
  //# sourceMappingURL=index.mjs.map
10180
10733
  //# sourceMappingURL=index.mjs.map