@peopl-health/nexus 6.0.0-dev.634 → 6.0.0-dev.649

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.
@@ -66,17 +66,22 @@ function buildIterationRecord(response, durationMs, apiCallConfig = {}) {
66
66
  const usage = response?.usage || {};
67
67
  const inputDetails = usage.input_tokens_details || {};
68
68
  const output = response?.output || [];
69
+ const content = Array.isArray(response?.content) ? response.content : [];
69
70
  return {
70
71
  model: apiCallConfig?.model || null,
71
72
  temperature: apiCallConfig?.temperature ?? null,
72
- maxOutputTokens: apiCallConfig?.max_output_tokens || null,
73
+ maxOutputTokens: apiCallConfig?.max_output_tokens || apiCallConfig?.max_tokens || null,
73
74
  stopReason: response?.stop_reason || response?.status || null,
74
75
  inputTokens: usage.input_tokens || 0,
75
76
  outputTokens: usage.output_tokens || 0,
76
- cacheCreationTokens: usage.cache_creation_tokens || inputDetails.cache_creation_tokens || 0,
77
- cacheReadTokens: usage.cache_read_tokens || inputDetails.cached_tokens || 0,
78
- reasoning: output.find((item) => item.type === 'reasoning')?.summary || null,
79
- toolCallIds: output.filter((item) => item.type === 'function_call').map((item) => item.call_id),
77
+ cacheCreationTokens: usage.cache_creation_tokens || usage.cache_creation_input_tokens || inputDetails.cache_creation_tokens || 0,
78
+ cacheReadTokens: usage.cache_read_tokens || usage.cache_read_input_tokens || inputDetails.cached_tokens || 0,
79
+ reasoning: output.find((item) => item.type === 'reasoning')?.summary
80
+ || content.find((block) => block.type === 'thinking')?.thinking || null,
81
+ toolCallIds: [
82
+ ...output.filter((item) => item.type === 'function_call').map((item) => item.call_id),
83
+ ...content.filter((block) => block.type === 'tool_use').map((block) => block.id),
84
+ ].filter((id) => typeof id === 'string' && id.length > 0),
80
85
  responseId: response?.id || null,
81
86
  durationMs,
82
87
  };
@@ -5,10 +5,14 @@ const { withTiming } = require('../../utils/tracingDecorator');
5
5
 
6
6
  const { logger } = require('../../utils/logger');
7
7
 
8
+ const runtimeConfig = require('../../config/runtimeConfig');
9
+
8
10
  const { BaseLLMProvider } = require('./BaseLLMProvider');
9
11
  const { handleFunctionCalls } = require('./OpenAIResponsesProviderTools');
10
12
 
11
13
  const DEFAULT_MAX_FUNCTION_ROUNDS = 5;
14
+ const CACHE_TTLS = ['5m', '1h'];
15
+ const DEFAULT_CACHE_TTL = '1h';
12
16
 
13
17
  class AnthropicProvider extends BaseLLMProvider {
14
18
  constructor(options = {}) {
@@ -21,6 +25,11 @@ class AnthropicProvider extends BaseLLMProvider {
21
25
 
22
26
  this.client = client || new Anthropic({ apiKey });
23
27
  this.maxFunctionRounds = maxFunctionRounds;
28
+ const cacheTtl = runtimeConfig.get('ANTHROPIC_CACHE_TTL', DEFAULT_CACHE_TTL);
29
+ if (!CACHE_TTLS.includes(cacheTtl)) {
30
+ logger.warn('[AnthropicProvider] Invalid ANTHROPIC_CACHE_TTL, falling back to default', { cacheTtl, default: DEFAULT_CACHE_TTL });
31
+ }
32
+ this.cacheTtl = CACHE_TTLS.includes(cacheTtl) ? cacheTtl : DEFAULT_CACHE_TTL;
24
33
  this.defaults = {
25
34
  maxOutputTokens: 400,
26
35
  ...defaultModels,
@@ -41,13 +50,15 @@ class AnthropicProvider extends BaseLLMProvider {
41
50
  const accumulatedUsage = { input_tokens: 0, output_tokens: 0, total_tokens: 0 };
42
51
  const addUsage = (usage) => {
43
52
  if (!usage) return;
44
- accumulatedUsage.input_tokens += usage.input_tokens || 0;
53
+ const inputTokens = (usage.input_tokens || 0) + (usage.cache_read_input_tokens || 0) + (usage.cache_creation_input_tokens || 0);
54
+ accumulatedUsage.input_tokens += inputTokens;
45
55
  accumulatedUsage.output_tokens += usage.output_tokens || 0;
46
- accumulatedUsage.total_tokens += (usage.input_tokens || 0) + (usage.output_tokens || 0);
56
+ accumulatedUsage.total_tokens += inputTokens + (usage.output_tokens || 0);
47
57
  };
48
58
 
49
59
  const { system, messages } = this._toAnthropicMessages(instructions, input);
50
- const apiCallConfig = { ...this._mapModelConfig(modelConfig), system };
60
+ const apiCallConfig = { ...this._mapModelConfig(modelConfig) };
61
+ if (system) apiCallConfig.system = system;
51
62
  if (toolSchemas.length > 0) {
52
63
  apiCallConfig.tools = this._mapTools(toolSchemas);
53
64
  apiCallConfig.tool_choice = this._mapToolChoice(toolChoice);
@@ -116,7 +127,11 @@ class AnthropicProvider extends BaseLLMProvider {
116
127
  messages.push({ role: item.role === 'assistant' ? 'assistant' : 'user', content });
117
128
  }
118
129
 
119
- return { system: systemParts.join('\n\n'), messages };
130
+ const system = systemParts.length
131
+ ? [{ type: 'text', text: systemParts.join('\n\n'), cache_control: { type: 'ephemeral', ttl: this.cacheTtl } }]
132
+ : null;
133
+
134
+ return { system, messages };
120
135
  }
121
136
 
122
137
  _mapModelConfig(modelConfig) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@peopl-health/nexus",
3
- "version": "6.0.0-dev.634",
3
+ "version": "6.0.0-dev.649",
4
4
  "description": "Core messaging and assistant library for WhatsApp communication platforms",
5
5
  "keywords": [
6
6
  "whatsapp",