@cognipeer/agent-sdk 0.4.6 → 0.4.8

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
@@ -1793,14 +1793,6 @@ var DEFAULT_PROFILE_CONFIGS = {
1793
1793
  schemaValidation: "strict",
1794
1794
  retryOnSchemaError: true,
1795
1795
  fallbackPolicy: "keep_structured"
1796
- },
1797
- watchdog: {
1798
- enabled: true,
1799
- tokenDriftThreshold: 1200,
1800
- overToolingSpikeThreshold: 0.7,
1801
- contextRotThreshold: 0.65,
1802
- autoCompaction: true,
1803
- autoReplanOnFailure: true
1804
1796
  }
1805
1797
  },
1806
1798
  balanced: {
@@ -1858,14 +1850,6 @@ var DEFAULT_PROFILE_CONFIGS = {
1858
1850
  schemaValidation: "strict",
1859
1851
  retryOnSchemaError: true,
1860
1852
  fallbackPolicy: "keep_structured"
1861
- },
1862
- watchdog: {
1863
- enabled: true,
1864
- tokenDriftThreshold: 1800,
1865
- overToolingSpikeThreshold: 0.6,
1866
- contextRotThreshold: 0.55,
1867
- autoCompaction: true,
1868
- autoReplanOnFailure: true
1869
1853
  }
1870
1854
  },
1871
1855
  deep: {
@@ -1923,14 +1907,6 @@ var DEFAULT_PROFILE_CONFIGS = {
1923
1907
  schemaValidation: "strict",
1924
1908
  retryOnSchemaError: true,
1925
1909
  fallbackPolicy: "keep_structured"
1926
- },
1927
- watchdog: {
1928
- enabled: true,
1929
- tokenDriftThreshold: 2200,
1930
- overToolingSpikeThreshold: 0.55,
1931
- contextRotThreshold: 0.5,
1932
- autoCompaction: true,
1933
- autoReplanOnFailure: true
1934
1910
  }
1935
1911
  },
1936
1912
  research: {
@@ -1988,14 +1964,6 @@ var DEFAULT_PROFILE_CONFIGS = {
1988
1964
  schemaValidation: "strict",
1989
1965
  retryOnSchemaError: true,
1990
1966
  fallbackPolicy: "keep_structured"
1991
- },
1992
- watchdog: {
1993
- enabled: true,
1994
- tokenDriftThreshold: 2600,
1995
- overToolingSpikeThreshold: 0.5,
1996
- contextRotThreshold: 0.45,
1997
- autoCompaction: true,
1998
- autoReplanOnFailure: true
1999
1967
  }
2000
1968
  }
2001
1969
  };
@@ -2072,11 +2040,6 @@ function normalizeSmartAgentOptions(opts) {
2072
2040
  ...opts.toolResponses?.toolResponseRetentionByTool || {}
2073
2041
  },
2074
2042
  criticalTools: opts.toolResponses?.criticalTools ?? customProfile.toolResponses?.criticalTools ?? preset.toolResponses.criticalTools
2075
- },
2076
- watchdog: {
2077
- ...preset.watchdog,
2078
- ...customProfile.watchdog || {},
2079
- ...opts.watchdog || {}
2080
2043
  }
2081
2044
  };
2082
2045
  }
@@ -2307,7 +2270,7 @@ function createToolsNode(initialTools, opts) {
2307
2270
  if (toolCallId) {
2308
2271
  ctx.__toolSchemaError = { toolName, toolCallId, message };
2309
2272
  }
2310
- if (resolved.watchdog.autoReplanOnFailure) {
2273
+ if (resolved.planning.replanPolicy === "on_failure") {
2311
2274
  ctx.__planNeedsReplan = true;
2312
2275
  }
2313
2276
  state.ctx = ctx;
@@ -2912,6 +2875,24 @@ function getLastAssistantMessage(messages) {
2912
2875
  }
2913
2876
  return void 0;
2914
2877
  }
2878
+ function getActiveSummarizationThreshold(opts) {
2879
+ const summarization = opts.summarization;
2880
+ if (!summarization || typeof summarization !== "object" || summarization.enable === false) {
2881
+ return void 0;
2882
+ }
2883
+ return summarization.summaryTriggerTokens || summarization.maxTokens || opts.limits?.maxContextTokens || 5e4;
2884
+ }
2885
+ function clearNeedsSummarization(state) {
2886
+ if (!state.ctx?.__needsSummarization) {
2887
+ return state;
2888
+ }
2889
+ const nextCtx = { ...state.ctx || {} };
2890
+ delete nextCtx.__needsSummarization;
2891
+ return {
2892
+ ...state,
2893
+ ctx: Object.keys(nextCtx).length > 0 ? nextCtx : void 0
2894
+ };
2895
+ }
2915
2896
  function createAgent(opts) {
2916
2897
  const resolver = createResolverNode();
2917
2898
  const agentCore = createAgentCoreNode(opts);
@@ -2960,6 +2941,7 @@ function createAgent(opts) {
2960
2941
  outputSchema: opts.outputSchema,
2961
2942
  tracing: opts.tracing
2962
2943
  };
2944
+ const summarizationThreshold = getActiveSummarizationThreshold(opts);
2963
2945
  async function runLoop(initial, config, emit) {
2964
2946
  let state = await resolver(initial);
2965
2947
  if (state.ctx?.__paused) {
@@ -2976,6 +2958,9 @@ function createAgent(opts) {
2976
2958
  delete nextCtx.__resumeStage;
2977
2959
  state = { ...state, ctx: Object.keys(nextCtx).length > 0 ? nextCtx : void 0 };
2978
2960
  }
2961
+ if (summarizationThreshold === void 0) {
2962
+ state = clearNeedsSummarization(state);
2963
+ }
2979
2964
  const mergedLimits = {
2980
2965
  ...opts.limits || {},
2981
2966
  ...config?.limits || {}
@@ -3084,25 +3069,18 @@ function createAgent(opts) {
3084
3069
  }
3085
3070
  }
3086
3071
  }
3087
- let maxTok;
3088
- if (opts.summarization && typeof opts.summarization === "object") {
3089
- maxTok = opts.summarization.summaryTriggerTokens || opts.summarization.maxTokens;
3090
- }
3091
- if (maxTok === void 0) {
3092
- maxTok = 5e4;
3093
- }
3094
- if (maxTok) {
3072
+ if (summarizationThreshold !== void 0) {
3095
3073
  const tokCountMessages = (state.messages || []).filter((message) => {
3096
3074
  if (isSyntheticSummaryMessage(message)) return false;
3097
3075
  if (message.role === "system" && (message.name === "context_summary" || message.name === "memory_context")) return false;
3098
3076
  return true;
3099
3077
  });
3100
3078
  const tokenCount = countMessagesTokens(tokCountMessages);
3101
- if (tokenCount > maxTok) {
3079
+ if (tokenCount > summarizationThreshold) {
3102
3080
  const hasFreshSummary = (state.messages || []).some(
3103
3081
  (m) => m.role === "tool" && typeof m.content === "string" && (m.content === "SUMMARIZED" || m.content.startsWith("SUMMARIZED_TOOL_RESPONSE"))
3104
3082
  );
3105
- if (hasFreshSummary && tokenCount <= maxTok * 1.15) ; else {
3083
+ if (hasFreshSummary && tokenCount <= summarizationThreshold * 1.15) ; else {
3106
3084
  const ctx = { ...state.ctx || {}, __needsSummarization: true };
3107
3085
  state = { ...state, ctx };
3108
3086
  break;
@@ -3591,15 +3569,6 @@ function buildModelMessages(state, config) {
3591
3569
  ];
3592
3570
  return clampToBudget(assembled, config.limits.maxContextTokens);
3593
3571
  }
3594
- function estimateContextRotScore(state) {
3595
- const summaryCount = state.summaryRecords?.length || 0;
3596
- const archivedCount = state.toolHistoryArchived?.length || 0;
3597
- const messageCount = state.messages?.length || 0;
3598
- const summarizedMessages = state.messages?.filter((message) => message.role === "tool" && typeof message.content === "string" && (message.content === "SUMMARIZED" || message.content.startsWith("SUMMARIZED_TOOL_RESPONSE"))).length || 0;
3599
- const numerator = summaryCount * 2 + archivedCount + summarizedMessages;
3600
- const denominator = Math.max(messageCount, 1);
3601
- return Number((numerator / denominator).toFixed(3));
3602
- }
3603
3572
 
3604
3573
  // src/nodes/contextSummarize.ts
3605
3574
  var systemMessage = (content) => ({ role: "system", content });
@@ -3744,6 +3713,9 @@ function findToolHistoryEntry(state, toolCallId, toolName) {
3744
3713
  }
3745
3714
  }
3746
3715
  }
3716
+ if (!toolName) {
3717
+ return void 0;
3718
+ }
3747
3719
  for (let index = entries.length - 1; index >= 0; index -= 1) {
3748
3720
  const entry = entries[index];
3749
3721
  if (entry?.toolName === toolName) {
@@ -3832,8 +3804,20 @@ function createContextSummarizeNode(opts) {
3832
3804
  const messages = state.messages || [];
3833
3805
  const onEvent = state.ctx?.__onEvent;
3834
3806
  const traceSession = state.ctx?.__traceSession;
3807
+ const toolResponsesConfigEarly = resolved.toolResponses;
3835
3808
  const compressableMessages = messages.filter(
3836
- (m) => m.role === "tool" && !isSummarizedToolPlaceholder(m.content) && !isSyntheticSummaryToolMessage(m)
3809
+ (m) => {
3810
+ if (m.role !== "tool") return false;
3811
+ if (isSummarizedToolPlaceholder(m.content)) return false;
3812
+ if (isSyntheticSummaryToolMessage(m)) return false;
3813
+ const histEntry = findToolHistoryEntry(state, m.tool_call_id, m.name);
3814
+ if (histEntry?.retentionPolicy === "keep_full") return false;
3815
+ if (!histEntry?.retentionPolicy) {
3816
+ const byTool = toolResponsesConfigEarly.toolResponseRetentionByTool?.[m.name || ""];
3817
+ if ((byTool || toolResponsesConfigEarly.defaultPolicy) === "keep_full") return false;
3818
+ }
3819
+ return true;
3820
+ }
3837
3821
  );
3838
3822
  if (compressableMessages.length === 0) {
3839
3823
  return {};
@@ -3854,6 +3838,13 @@ function createContextSummarizeNode(opts) {
3854
3838
  else if (Array.isArray(m.content)) {
3855
3839
  content = m.content.map((c) => c.text || JSON.stringify(c)).join(" ");
3856
3840
  }
3841
+ if (m.role === "tool" && isSummarizedToolPlaceholder(content)) {
3842
+ const historyEntry = findToolHistoryEntry(state, m.tool_call_id, m.name);
3843
+ if (historyEntry) {
3844
+ const original = historyEntry.rawOutput ?? historyEntry.output;
3845
+ content = typeof original === "string" ? original : JSON.stringify(original);
3846
+ }
3847
+ }
3857
3848
  const maxContentLength = 2e3;
3858
3849
  if (content.length > maxContentLength) {
3859
3850
  content = content.substring(0, maxContentLength) + "... [TRUNCATED]";
@@ -3989,6 +3980,23 @@ ${canonicalFacts.length > 0 ? canonicalFacts.map((fact) => `- ${fact.key}: ${fac
3989
3980
  });
3990
3981
  }
3991
3982
  });
3983
+ const protectedToolCallIds = /* @__PURE__ */ new Set();
3984
+ for (let i = messages.length - 1; i >= 0; i--) {
3985
+ const m = messages[i];
3986
+ if (m.role === "assistant" && Array.isArray(m.tool_calls) && m.tool_calls.length > 0) {
3987
+ const thisToolCallIds = new Set(m.tool_calls.map((tc) => tc.id).filter(Boolean));
3988
+ const otherCompressable = compressableMessages.filter(
3989
+ (cm) => !thisToolCallIds.has(cm.tool_call_id)
3990
+ );
3991
+ if (otherCompressable.length > 0) {
3992
+ for (const tc of m.tool_calls) {
3993
+ if (tc.id) protectedToolCallIds.add(tc.id);
3994
+ }
3995
+ }
3996
+ break;
3997
+ }
3998
+ }
3999
+ const toolResponsesConfig = resolved.toolResponses;
3992
4000
  const newMessages = messages.map((m) => {
3993
4001
  if (m.role === "tool") {
3994
4002
  if (isSyntheticSummaryToolMessage(m)) {
@@ -3999,6 +4007,16 @@ ${canonicalFacts.length > 0 ? canonicalFacts.map((fact) => `- ${fact.key}: ${fac
3999
4007
  return null;
4000
4008
  }
4001
4009
  if (isSummarizedToolPlaceholder(m.content)) return m;
4010
+ if (toolCallId && protectedToolCallIds.has(toolCallId)) return m;
4011
+ const toolName = m.name || "";
4012
+ const historyEntry = findToolHistoryEntry(state, toolCallId, toolName);
4013
+ const entryRetention = historyEntry?.retentionPolicy;
4014
+ if (entryRetention === "keep_full") return m;
4015
+ if (!entryRetention) {
4016
+ const byTool = toolResponsesConfig.toolResponseRetentionByTool?.[toolName];
4017
+ const configPolicy = byTool || toolResponsesConfig.defaultPolicy;
4018
+ if (configPolicy === "keep_full") return m;
4019
+ }
4002
4020
  return {
4003
4021
  ...m,
4004
4022
  content: buildSummarizedToolMessage(m, state)
@@ -4006,6 +4024,12 @@ ${canonicalFacts.length > 0 ? canonicalFacts.map((fact) => `- ${fact.key}: ${fac
4006
4024
  }
4007
4025
  return m;
4008
4026
  }).filter((m) => m !== null);
4027
+ const actuallyCompressed = newMessages.filter(
4028
+ (m) => m.role === "tool" && typeof m.content === "string" && m.content.startsWith("SUMMARIZED_TOOL_RESPONSE") && !messages.some((orig) => orig.tool_call_id === m.tool_call_id && isSummarizedToolPlaceholder(orig.content))
4029
+ );
4030
+ if (actuallyCompressed.length === 0) {
4031
+ return {};
4032
+ }
4009
4033
  const validatedMessages = validateMessageSequence(newMessages);
4010
4034
  const summaryToolCallId = `call_summary_${Date.now()}`;
4011
4035
  const assistantSummaryCall = {
@@ -4081,12 +4105,7 @@ ${canonicalFacts.length > 0 ? canonicalFacts.map((fact) => `- ${fact.key}: ${fac
4081
4105
  return {
4082
4106
  messages: finalMessages,
4083
4107
  summaries,
4084
- summaryRecords,
4085
- watchdog: {
4086
- ...state.watchdog || {},
4087
- compactions: (state.watchdog?.compactions || 0) + 1,
4088
- lastAction: "summarized"
4089
- }
4108
+ summaryRecords
4090
4109
  };
4091
4110
  };
4092
4111
  }
@@ -4385,8 +4404,7 @@ function needsSummarization(state, opts, summarizationEnabled) {
4385
4404
  return "";
4386
4405
  }).join("\n");
4387
4406
  const tokenCount = countApproxTokens(allText);
4388
- const contextRotScore = state.watchdog?.contextRotScore || 0;
4389
- const needsSum = tokenCount > maxTok || resolved.watchdog.enabled && resolved.watchdog.autoCompaction && contextRotScore >= resolved.watchdog.contextRotThreshold;
4407
+ const needsSum = tokenCount > maxTok;
4390
4408
  if (process.env.DEBUG_SUMMARIZATION) {
4391
4409
  const msgCount = (state.messages || []).length;
4392
4410
  const toolMsgs = (state.messages || []).filter((m) => m.role === "tool");
@@ -4396,7 +4414,7 @@ function needsSummarization(state, opts, summarizationEnabled) {
4396
4414
  });
4397
4415
  console.log(`[Summarization] Messages: ${msgCount}, Tool messages: ${toolMsgs.length}`);
4398
4416
  toolDetails.forEach((d) => console.log(` ${d}`));
4399
- console.log(`[Summarization] Token count: ${tokenCount}, Max: ${maxTok}, Context rot: ${contextRotScore}, Needs summarization: ${needsSum}`);
4417
+ console.log(`[Summarization] Token count: ${tokenCount}, Max: ${maxTok}, Needs summarization: ${needsSum}`);
4400
4418
  }
4401
4419
  return needsSum;
4402
4420
  } catch {
@@ -4550,7 +4568,6 @@ function createSmartAgent(opts) {
4550
4568
  delegation: resolved.delegation,
4551
4569
  memory: { ...resolved.memory, store: memoryStore },
4552
4570
  toolResponses: resolved.toolResponses,
4553
- watchdog: resolved.watchdog,
4554
4571
  useTodoList: planningEnabled
4555
4572
  };
4556
4573
  const stateRef = { toolHistory: void 0, toolHistoryArchived: void 0, todoList: void 0, planVersion: 0, adherenceScore: 0 };
@@ -4633,7 +4650,6 @@ function createSmartAgent(opts) {
4633
4650
  let rawMessages = [...seedMessages];
4634
4651
  const effectiveMaxToolCalls = config?.limits?.maxToolCalls ?? resolved.limits.maxToolCalls ?? 10;
4635
4652
  const iterationLimit = Math.max(effectiveMaxToolCalls * 3 + 5, 30);
4636
- let previousTokenCount = countApproxTokens(rawMessages.map((message) => typeof message.content === "string" ? message.content : JSON.stringify(message.content)).join("\n"));
4637
4653
  for (let i = 0; i < iterationLimit; i++) {
4638
4654
  state = { ...state, messages: rawMessages };
4639
4655
  const next = summarizationEnabled ? decideBefore(state) : "agent";
@@ -4667,27 +4683,6 @@ function createSmartAgent(opts) {
4667
4683
  state = syncPlanState(await syncMemory(state));
4668
4684
  stateRef.toolHistory = state.toolHistory;
4669
4685
  stateRef.toolHistoryArchived = state.toolHistoryArchived;
4670
- const currentTokenCount = countApproxTokens(rawMessages.map((message) => typeof message.content === "string" ? message.content : JSON.stringify(message.content)).join("\n"));
4671
- const tokenDrift = Math.max(0, currentTokenCount - previousTokenCount);
4672
- const toolMessagesThisTurn = appendedMessages.filter((message) => message.role === "tool").length;
4673
- const overToolingRate = appendedMessages.length === 0 ? 0 : Number((toolMessagesThisTurn / appendedMessages.length).toFixed(2));
4674
- state = {
4675
- ...state,
4676
- watchdog: {
4677
- tokenDrift,
4678
- contextRotScore: estimateContextRotScore(state),
4679
- overToolingRate,
4680
- compactions: state.watchdog?.compactions || 0,
4681
- lastAction: appendedMessages.length > 0 ? "agent_turn" : state.watchdog?.lastAction
4682
- }
4683
- };
4684
- previousTokenCount = currentTokenCount;
4685
- if (resolved.watchdog.enabled && resolved.watchdog.autoCompaction) {
4686
- const shouldCompact = tokenDrift >= resolved.watchdog.tokenDriftThreshold || (state.watchdog?.overToolingRate || 0) >= resolved.watchdog.overToolingSpikeThreshold || (state.watchdog?.contextRotScore || 0) >= resolved.watchdog.contextRotThreshold;
4687
- if (shouldCompact) {
4688
- state = { ...state, ctx: { ...state.ctx || {}, __needsSummarization: true } };
4689
- }
4690
- }
4691
4686
  if (state.ctx?.__needsSummarization && summarizer) {
4692
4687
  const ctx = { ...state.ctx || {} };
4693
4688
  delete ctx.__needsSummarization;
@@ -4719,12 +4714,12 @@ function createSmartAgent(opts) {
4719
4714
  }
4720
4715
  if (state.summaries && state.summaries.length > 0) {
4721
4716
  if (lastResult.state) {
4722
- lastResult = { ...lastResult, state: { ...lastResult.state, summaries: state.summaries, summaryRecords: state.summaryRecords, memoryFacts: state.memoryFacts, plan: state.plan, planVersion: state.planVersion, watchdog: state.watchdog, messages: rawMessages } };
4717
+ lastResult = { ...lastResult, state: { ...lastResult.state, summaries: state.summaries, summaryRecords: state.summaryRecords, memoryFacts: state.memoryFacts, plan: state.plan, planVersion: state.planVersion, messages: rawMessages } };
4723
4718
  } else {
4724
- lastResult = { ...lastResult, state: { ...state, summaries: state.summaries, summaryRecords: state.summaryRecords, memoryFacts: state.memoryFacts, plan: state.plan, planVersion: state.planVersion, watchdog: state.watchdog, messages: rawMessages } };
4719
+ lastResult = { ...lastResult, state: { ...state, summaries: state.summaries, summaryRecords: state.summaryRecords, memoryFacts: state.memoryFacts, plan: state.plan, planVersion: state.planVersion, messages: rawMessages } };
4725
4720
  }
4726
4721
  } else if (lastResult.state) {
4727
- lastResult = { ...lastResult, state: { ...lastResult.state, memoryFacts: state.memoryFacts, plan: state.plan, planVersion: state.planVersion, watchdog: state.watchdog, messages: rawMessages } };
4722
+ lastResult = { ...lastResult, state: { ...lastResult.state, memoryFacts: state.memoryFacts, plan: state.plan, planVersion: state.planVersion, messages: rawMessages } };
4728
4723
  }
4729
4724
  return lastResult;
4730
4725
  },