@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.mjs CHANGED
@@ -2887,6 +2887,39 @@ function isSyntheticSummaryMessage(message) {
2887
2887
  }
2888
2888
  return false;
2889
2889
  }
2890
+ function getMessageText(message) {
2891
+ if (typeof message?.content === "string") return message.content;
2892
+ if (Array.isArray(message?.content)) {
2893
+ return message.content.map((chunk) => typeof chunk === "string" ? chunk : chunk?.text ?? chunk?.content ?? "").join("");
2894
+ }
2895
+ return "";
2896
+ }
2897
+ function getLastAssistantMessage(messages) {
2898
+ for (let index = messages.length - 1; index >= 0; index -= 1) {
2899
+ if (messages[index]?.role === "assistant") {
2900
+ return messages[index];
2901
+ }
2902
+ }
2903
+ return void 0;
2904
+ }
2905
+ function getActiveSummarizationThreshold(opts) {
2906
+ const summarization = opts.summarization;
2907
+ if (!summarization || typeof summarization !== "object" || summarization.enable === false) {
2908
+ return void 0;
2909
+ }
2910
+ return summarization.summaryTriggerTokens || summarization.maxTokens || opts.limits?.maxContextTokens || 5e4;
2911
+ }
2912
+ function clearNeedsSummarization(state) {
2913
+ if (!state.ctx?.__needsSummarization) {
2914
+ return state;
2915
+ }
2916
+ const nextCtx = { ...state.ctx || {} };
2917
+ delete nextCtx.__needsSummarization;
2918
+ return {
2919
+ ...state,
2920
+ ctx: Object.keys(nextCtx).length > 0 ? nextCtx : void 0
2921
+ };
2922
+ }
2890
2923
  function createAgent(opts) {
2891
2924
  const resolver = createResolverNode();
2892
2925
  const agentCore = createAgentCoreNode(opts);
@@ -2935,6 +2968,7 @@ function createAgent(opts) {
2935
2968
  outputSchema: opts.outputSchema,
2936
2969
  tracing: opts.tracing
2937
2970
  };
2971
+ const summarizationThreshold = getActiveSummarizationThreshold(opts);
2938
2972
  async function runLoop(initial, config, emit) {
2939
2973
  let state = await resolver(initial);
2940
2974
  if (state.ctx?.__paused) {
@@ -2951,6 +2985,9 @@ function createAgent(opts) {
2951
2985
  delete nextCtx.__resumeStage;
2952
2986
  state = { ...state, ctx: Object.keys(nextCtx).length > 0 ? nextCtx : void 0 };
2953
2987
  }
2988
+ if (summarizationThreshold === void 0) {
2989
+ state = clearNeedsSummarization(state);
2990
+ }
2954
2991
  const mergedLimits = {
2955
2992
  ...opts.limits || {},
2956
2993
  ...config?.limits || {}
@@ -3059,25 +3096,18 @@ function createAgent(opts) {
3059
3096
  }
3060
3097
  }
3061
3098
  }
3062
- let maxTok;
3063
- if (opts.summarization && typeof opts.summarization === "object") {
3064
- maxTok = opts.summarization.summaryTriggerTokens || opts.summarization.maxTokens;
3065
- }
3066
- if (maxTok === void 0) {
3067
- maxTok = 5e4;
3068
- }
3069
- if (maxTok) {
3099
+ if (summarizationThreshold !== void 0) {
3070
3100
  const tokCountMessages = (state.messages || []).filter((message) => {
3071
3101
  if (isSyntheticSummaryMessage(message)) return false;
3072
3102
  if (message.role === "system" && (message.name === "context_summary" || message.name === "memory_context")) return false;
3073
3103
  return true;
3074
3104
  });
3075
3105
  const tokenCount = countMessagesTokens(tokCountMessages);
3076
- if (tokenCount > maxTok) {
3106
+ if (tokenCount > summarizationThreshold) {
3077
3107
  const hasFreshSummary = (state.messages || []).some(
3078
3108
  (m) => m.role === "tool" && typeof m.content === "string" && (m.content === "SUMMARIZED" || m.content.startsWith("SUMMARIZED_TOOL_RESPONSE"))
3079
3109
  );
3080
- if (hasFreshSummary && tokenCount <= maxTok * 1.15) ; else {
3110
+ if (hasFreshSummary && tokenCount <= summarizationThreshold * 1.15) ; else {
3081
3111
  const ctx = { ...state.ctx || {}, __needsSummarization: true };
3082
3112
  state = { ...state, ctx };
3083
3113
  break;
@@ -3190,10 +3220,25 @@ function createAgent(opts) {
3190
3220
  } catch (err) {
3191
3221
  const errMsg = err instanceof Error ? err.message : String(err);
3192
3222
  emit?.({ type: "metadata", error: `Structured output force-finalize failed: ${errMsg}` });
3223
+ throw err;
3193
3224
  }
3194
3225
  }
3195
3226
  }
3196
3227
  }
3228
+ if (state.ctx?.__needsSummarization && !opts?.summarization) {
3229
+ throw new Error(
3230
+ "Agent context exceeded the available budget before a final assistant response could be generated. Reduce tool response size or use createSmartAgent with summarization enabled."
3231
+ );
3232
+ }
3233
+ const lastAfterLoop = state.messages[state.messages.length - 1];
3234
+ if (lastAfterLoop?.role === "tool" && !pausedStage) {
3235
+ const isExpectedExit = state.ctx?.__awaitingApproval || state.ctx?.__cancelled || state.ctx?.__finalizedDueToStructuredOutput || state.ctx?.__finalizedDueToToolLimit || state.ctx?.__needsSummarization;
3236
+ if (!isExpectedExit) {
3237
+ throw new Error(
3238
+ "Agent loop terminated with a pending tool response but no subsequent model invocation. This usually indicates a model provider error or exhausted iteration budget."
3239
+ );
3240
+ }
3241
+ }
3197
3242
  if (!pausedStage && typeof onStateChange === "function" && onStateChange(state)) {
3198
3243
  checkpointIfRequested("after_loop");
3199
3244
  }
@@ -3263,10 +3308,8 @@ function createAgent(opts) {
3263
3308
  agentRuntime: res.agent || runtime,
3264
3309
  status: "success"
3265
3310
  });
3266
- const finalMsg = res.messages[res.messages.length - 1];
3267
- let content = "";
3268
- if (typeof finalMsg?.content === "string") content = finalMsg.content;
3269
- else if (Array.isArray(finalMsg?.content)) content = finalMsg.content.map((c) => typeof c === "string" ? c : c?.text ?? c?.content ?? "").join("");
3311
+ const finalAssistantMsg = getLastAssistantMessage(res.messages);
3312
+ const content = getMessageText(finalAssistantMsg);
3270
3313
  let parsed = void 0;
3271
3314
  const schema = opts.outputSchema;
3272
3315
  if (schema && res.ctx?.__structuredOutputParsed) {
@@ -3287,7 +3330,7 @@ function createAgent(opts) {
3287
3330
  } catch {
3288
3331
  }
3289
3332
  }
3290
- emit({ type: "finalAnswer", content: typeof finalMsg?.content === "string" ? finalMsg.content : content });
3333
+ emit({ type: "finalAnswer", content });
3291
3334
  if (streamEnabled && content) {
3292
3335
  onStream?.({ text: content, isFinal: true });
3293
3336
  emit({ type: "stream", text: content, isFinal: true });