@cognipeer/agent-sdk 0.4.5 → 0.4.7

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
@@ -2897,6 +2897,39 @@ function isSyntheticSummaryMessage(message) {
2897
2897
  }
2898
2898
  return false;
2899
2899
  }
2900
+ function getMessageText(message) {
2901
+ if (typeof message?.content === "string") return message.content;
2902
+ if (Array.isArray(message?.content)) {
2903
+ return message.content.map((chunk) => typeof chunk === "string" ? chunk : chunk?.text ?? chunk?.content ?? "").join("");
2904
+ }
2905
+ return "";
2906
+ }
2907
+ function getLastAssistantMessage(messages) {
2908
+ for (let index = messages.length - 1; index >= 0; index -= 1) {
2909
+ if (messages[index]?.role === "assistant") {
2910
+ return messages[index];
2911
+ }
2912
+ }
2913
+ return void 0;
2914
+ }
2915
+ function getActiveSummarizationThreshold(opts) {
2916
+ const summarization = opts.summarization;
2917
+ if (!summarization || typeof summarization !== "object" || summarization.enable === false) {
2918
+ return void 0;
2919
+ }
2920
+ return summarization.summaryTriggerTokens || summarization.maxTokens || opts.limits?.maxContextTokens || 5e4;
2921
+ }
2922
+ function clearNeedsSummarization(state) {
2923
+ if (!state.ctx?.__needsSummarization) {
2924
+ return state;
2925
+ }
2926
+ const nextCtx = { ...state.ctx || {} };
2927
+ delete nextCtx.__needsSummarization;
2928
+ return {
2929
+ ...state,
2930
+ ctx: Object.keys(nextCtx).length > 0 ? nextCtx : void 0
2931
+ };
2932
+ }
2900
2933
  function createAgent(opts) {
2901
2934
  const resolver = createResolverNode();
2902
2935
  const agentCore = createAgentCoreNode(opts);
@@ -2945,6 +2978,7 @@ function createAgent(opts) {
2945
2978
  outputSchema: opts.outputSchema,
2946
2979
  tracing: opts.tracing
2947
2980
  };
2981
+ const summarizationThreshold = getActiveSummarizationThreshold(opts);
2948
2982
  async function runLoop(initial, config, emit) {
2949
2983
  let state = await resolver(initial);
2950
2984
  if (state.ctx?.__paused) {
@@ -2961,6 +2995,9 @@ function createAgent(opts) {
2961
2995
  delete nextCtx.__resumeStage;
2962
2996
  state = { ...state, ctx: Object.keys(nextCtx).length > 0 ? nextCtx : void 0 };
2963
2997
  }
2998
+ if (summarizationThreshold === void 0) {
2999
+ state = clearNeedsSummarization(state);
3000
+ }
2964
3001
  const mergedLimits = {
2965
3002
  ...opts.limits || {},
2966
3003
  ...config?.limits || {}
@@ -3069,25 +3106,18 @@ function createAgent(opts) {
3069
3106
  }
3070
3107
  }
3071
3108
  }
3072
- let maxTok;
3073
- if (opts.summarization && typeof opts.summarization === "object") {
3074
- maxTok = opts.summarization.summaryTriggerTokens || opts.summarization.maxTokens;
3075
- }
3076
- if (maxTok === void 0) {
3077
- maxTok = 5e4;
3078
- }
3079
- if (maxTok) {
3109
+ if (summarizationThreshold !== void 0) {
3080
3110
  const tokCountMessages = (state.messages || []).filter((message) => {
3081
3111
  if (isSyntheticSummaryMessage(message)) return false;
3082
3112
  if (message.role === "system" && (message.name === "context_summary" || message.name === "memory_context")) return false;
3083
3113
  return true;
3084
3114
  });
3085
3115
  const tokenCount = countMessagesTokens(tokCountMessages);
3086
- if (tokenCount > maxTok) {
3116
+ if (tokenCount > summarizationThreshold) {
3087
3117
  const hasFreshSummary = (state.messages || []).some(
3088
3118
  (m) => m.role === "tool" && typeof m.content === "string" && (m.content === "SUMMARIZED" || m.content.startsWith("SUMMARIZED_TOOL_RESPONSE"))
3089
3119
  );
3090
- if (hasFreshSummary && tokenCount <= maxTok * 1.15) ; else {
3120
+ if (hasFreshSummary && tokenCount <= summarizationThreshold * 1.15) ; else {
3091
3121
  const ctx = { ...state.ctx || {}, __needsSummarization: true };
3092
3122
  state = { ...state, ctx };
3093
3123
  break;
@@ -3200,10 +3230,25 @@ function createAgent(opts) {
3200
3230
  } catch (err) {
3201
3231
  const errMsg = err instanceof Error ? err.message : String(err);
3202
3232
  emit?.({ type: "metadata", error: `Structured output force-finalize failed: ${errMsg}` });
3233
+ throw err;
3203
3234
  }
3204
3235
  }
3205
3236
  }
3206
3237
  }
3238
+ if (state.ctx?.__needsSummarization && !opts?.summarization) {
3239
+ throw new Error(
3240
+ "Agent context exceeded the available budget before a final assistant response could be generated. Reduce tool response size or use createSmartAgent with summarization enabled."
3241
+ );
3242
+ }
3243
+ const lastAfterLoop = state.messages[state.messages.length - 1];
3244
+ if (lastAfterLoop?.role === "tool" && !pausedStage) {
3245
+ const isExpectedExit = state.ctx?.__awaitingApproval || state.ctx?.__cancelled || state.ctx?.__finalizedDueToStructuredOutput || state.ctx?.__finalizedDueToToolLimit || state.ctx?.__needsSummarization;
3246
+ if (!isExpectedExit) {
3247
+ throw new Error(
3248
+ "Agent loop terminated with a pending tool response but no subsequent model invocation. This usually indicates a model provider error or exhausted iteration budget."
3249
+ );
3250
+ }
3251
+ }
3207
3252
  if (!pausedStage && typeof onStateChange === "function" && onStateChange(state)) {
3208
3253
  checkpointIfRequested("after_loop");
3209
3254
  }
@@ -3273,10 +3318,8 @@ function createAgent(opts) {
3273
3318
  agentRuntime: res.agent || runtime,
3274
3319
  status: "success"
3275
3320
  });
3276
- const finalMsg = res.messages[res.messages.length - 1];
3277
- let content = "";
3278
- if (typeof finalMsg?.content === "string") content = finalMsg.content;
3279
- else if (Array.isArray(finalMsg?.content)) content = finalMsg.content.map((c) => typeof c === "string" ? c : c?.text ?? c?.content ?? "").join("");
3321
+ const finalAssistantMsg = getLastAssistantMessage(res.messages);
3322
+ const content = getMessageText(finalAssistantMsg);
3280
3323
  let parsed = void 0;
3281
3324
  const schema = opts.outputSchema;
3282
3325
  if (schema && res.ctx?.__structuredOutputParsed) {
@@ -3297,7 +3340,7 @@ function createAgent(opts) {
3297
3340
  } catch {
3298
3341
  }
3299
3342
  }
3300
- emit({ type: "finalAnswer", content: typeof finalMsg?.content === "string" ? finalMsg.content : content });
3343
+ emit({ type: "finalAnswer", content });
3301
3344
  if (streamEnabled && content) {
3302
3345
  onStream?.({ text: content, isFinal: true });
3303
3346
  emit({ type: "stream", text: content, isFinal: true });