@peopl-health/nexus 3.8.0 → 3.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/lib/eval/EvalProvider.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
const { OpenAI } = require('openai');
|
|
2
2
|
|
|
3
|
-
const { Config_ID } = require('../config/airtableConfig');
|
|
4
3
|
const { getCurrentMexicoDateTime } = require('../utils/dateUtils');
|
|
5
4
|
const { retryWithBackoff } = require('../utils/retryUtils');
|
|
6
5
|
const { logger } = require('../utils/logger');
|
|
@@ -8,7 +7,7 @@ const { Thread } = require('../models/threadModel');
|
|
|
8
7
|
const { DefaultMemoryManager } = require('../memory/DefaultMemoryManager');
|
|
9
8
|
const { OpenAIResponsesProvider } = require('../providers/OpenAIResponsesProvider');
|
|
10
9
|
const { handleFunctionCalls } = require('../providers/OpenAIResponsesProviderTools');
|
|
11
|
-
const {
|
|
10
|
+
const { composePrompt } = require('../services/promptComposerService');
|
|
12
11
|
const { getAssistantById } = require('../services/assistantResolver');
|
|
13
12
|
|
|
14
13
|
const MAX_FUNCTION_ROUNDS = parseInt(process.env.MAX_FUNCTION_ROUNDS || '5', 10);
|
|
@@ -108,12 +107,15 @@ class EvalProvider {
|
|
|
108
107
|
async _resolvePrompt(fallbackPrompt, assistantId, thread, promptVariables) {
|
|
109
108
|
let devContent;
|
|
110
109
|
if (this.promptSource === 'airtable' && assistantId) {
|
|
111
|
-
const
|
|
112
|
-
|
|
110
|
+
const { resolvedPrompt } = await composePrompt({
|
|
111
|
+
promptId: assistantId,
|
|
112
|
+
variables: promptVariables,
|
|
113
|
+
});
|
|
114
|
+
devContent = resolvedPrompt;
|
|
113
115
|
} else {
|
|
114
116
|
devContent = fallbackPrompt;
|
|
117
|
+
devContent = devContent.replace(/\{\{(\w+)\}\}/g, (_, key) => promptVariables[key] ?? '');
|
|
115
118
|
}
|
|
116
|
-
devContent = devContent.replace(/\{\{(\w+)\}\}/g, (_, key) => promptVariables[key] ?? '');
|
|
117
119
|
|
|
118
120
|
let assistant = null;
|
|
119
121
|
let toolSchemas = [];
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
const { OpenAI } = require('openai');
|
|
2
2
|
|
|
3
|
-
const { Config_ID } = require('../config/airtableConfig');
|
|
4
|
-
|
|
5
3
|
const { retryWithBackoff } = require('../utils/retryUtils');
|
|
6
4
|
const { logger } = require('../utils/logger');
|
|
7
5
|
const { getCurrentMexicoDateTime } = require('../utils/dateUtils');
|
|
@@ -10,7 +8,7 @@ const { DefaultMemoryManager } = require('../memory/DefaultMemoryManager');
|
|
|
10
8
|
|
|
11
9
|
const { getLastNMessages } = require('../helpers/messageHelper');
|
|
12
10
|
|
|
13
|
-
const {
|
|
11
|
+
const { composePrompt, resolveTools } = require('../services/promptComposerService');
|
|
14
12
|
const { handleFunctionCalls } = require('./OpenAIResponsesProviderTools');
|
|
15
13
|
|
|
16
14
|
const CONVERSATION_PREFIX = 'conv_';
|
|
@@ -314,12 +312,16 @@ class OpenAIResponsesProvider {
|
|
|
314
312
|
accumulatedUsage.total_tokens += usage.total_tokens || 0;
|
|
315
313
|
};
|
|
316
314
|
|
|
317
|
-
const
|
|
318
|
-
|
|
319
|
-
|
|
315
|
+
const { resolvedPrompt, snippetIds } = await composePrompt({
|
|
316
|
+
promptId: assistantId,
|
|
317
|
+
variables: promptVariables,
|
|
318
|
+
});
|
|
320
319
|
|
|
320
|
+
const { toolIds, filtered } = await resolveTools({ promptId: assistantId, assistant });
|
|
321
|
+
let devContent = resolvedPrompt;
|
|
321
322
|
if (assistant?.tools?.size) {
|
|
322
|
-
const
|
|
323
|
+
const activeToolNames = filtered ? toolIds : Array.from(assistant.tools.keys());
|
|
324
|
+
const toolNames = activeToolNames.join(', ');
|
|
323
325
|
devContent += `\n\nYou only have access to these tools: ${toolNames}. Do not call or reference any tools not listed here.`;
|
|
324
326
|
}
|
|
325
327
|
|
|
@@ -376,6 +378,9 @@ class OpenAIResponsesProvider {
|
|
|
376
378
|
tools_executed: allToolsExecuted,
|
|
377
379
|
retries: totalRetries,
|
|
378
380
|
usage: accumulatedUsage,
|
|
381
|
+
resolved_prompt: devContent,
|
|
382
|
+
snippet_ids: snippetIds,
|
|
383
|
+
tool_ids: toolIds,
|
|
379
384
|
};
|
|
380
385
|
}
|
|
381
386
|
|
|
@@ -243,6 +243,9 @@ const replyAssistantCore = async (code, message_ = null, thread_ = null, runOpti
|
|
|
243
243
|
const response_id = runResult.run?.id || null;
|
|
244
244
|
const usage = runResult.run?.usage || null;
|
|
245
245
|
const model = runResult.run?.model || null;
|
|
246
|
+
const resolved_prompt = runResult.run?.resolved_prompt || null;
|
|
247
|
+
const snippet_ids = runResult.run?.snippet_ids || [];
|
|
248
|
+
const tool_ids = runResult.run?.tool_ids || [];
|
|
246
249
|
|
|
247
250
|
const output = sanitizeOutput(rawOutput);
|
|
248
251
|
if (rawOutput !== output) {
|
|
@@ -294,6 +297,9 @@ const replyAssistantCore = async (code, message_ = null, thread_ = null, runOpti
|
|
|
294
297
|
prompt_config: prompt || null,
|
|
295
298
|
response_id: response_id || null,
|
|
296
299
|
context_message_count: lastMessage?.length || null,
|
|
300
|
+
resolved_prompt: resolved_prompt,
|
|
301
|
+
snippet_ids: snippet_ids,
|
|
302
|
+
tool_ids: tool_ids,
|
|
297
303
|
}).catch(err => logger.error('[replyAssistant] Failed to store metrics', { error: err.message }));
|
|
298
304
|
|
|
299
305
|
const alertThreshold = parseInt(process.env.TOKEN_ALERT_THRESHOLD, 10);
|
|
@@ -10,6 +10,7 @@ const CACHE_TTL = 5 * 60 * 1000;
|
|
|
10
10
|
|
|
11
11
|
const promptCache = new MapCache({ maxSize: 50, ttl: CACHE_TTL });
|
|
12
12
|
const snippetCache = new MapCache({ maxSize: 200, ttl: CACHE_TTL });
|
|
13
|
+
const toolCache = new MapCache({ maxSize: 50, ttl: CACHE_TTL });
|
|
13
14
|
|
|
14
15
|
async function fetchBasePrompt(promptId) {
|
|
15
16
|
const cacheKey = `prompt:${promptId}`;
|
|
@@ -86,9 +87,66 @@ async function composePrompt({ promptId, variables = null, status = null }) {
|
|
|
86
87
|
return { resolvedPrompt, snippetIds };
|
|
87
88
|
}
|
|
88
89
|
|
|
90
|
+
async function fetchToolMapping(promptId) {
|
|
91
|
+
const cacheKey = `tools:${promptId}`;
|
|
92
|
+
const cached = toolCache.get(cacheKey);
|
|
93
|
+
if (cached) return cached;
|
|
94
|
+
|
|
95
|
+
try {
|
|
96
|
+
const records = await getRecordByFilter(
|
|
97
|
+
Config_ID,
|
|
98
|
+
'tools',
|
|
99
|
+
`FIND("${promptId}", ARRAYJOIN({prompts}))`,
|
|
100
|
+
);
|
|
101
|
+
const tools = records || [];
|
|
102
|
+
toolCache.set(cacheKey, tools);
|
|
103
|
+
return tools;
|
|
104
|
+
} catch (error) {
|
|
105
|
+
logger.warn('[promptComposer] Failed to fetch tool mapping, using all registered tools', {
|
|
106
|
+
promptId, error: error.message,
|
|
107
|
+
});
|
|
108
|
+
return [];
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
async function resolveTools({ promptId, assistant, status = null }) {
|
|
113
|
+
if (!assistant?.tools?.size) return { toolIds: [], filtered: false };
|
|
114
|
+
|
|
115
|
+
const mappedTools = await fetchToolMapping(promptId);
|
|
116
|
+
if (!mappedTools.length) return { toolIds: [], filtered: false };
|
|
117
|
+
|
|
118
|
+
const activeTools = status
|
|
119
|
+
? mappedTools.filter(t => !t.status || t.status === status)
|
|
120
|
+
: mappedTools;
|
|
121
|
+
|
|
122
|
+
const registeredNames = new Set(assistant.tools.keys());
|
|
123
|
+
const validToolIds = [];
|
|
124
|
+
|
|
125
|
+
for (const tool of activeTools) {
|
|
126
|
+
const id = tool.tool_id;
|
|
127
|
+
if (registeredNames.has(id)) {
|
|
128
|
+
validToolIds.push(id);
|
|
129
|
+
} else {
|
|
130
|
+
logger.warn('[promptComposer] Tool mapped in Airtable but not registered in code', {
|
|
131
|
+
toolId: id, promptId,
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
logger.debug('[promptComposer] Tools resolved', {
|
|
137
|
+
promptId,
|
|
138
|
+
mapped: activeTools.length,
|
|
139
|
+
valid: validToolIds.length,
|
|
140
|
+
filtered: true,
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
return { toolIds: validToolIds, filtered: true };
|
|
144
|
+
}
|
|
145
|
+
|
|
89
146
|
function clearCache() {
|
|
90
147
|
promptCache.clear();
|
|
91
148
|
snippetCache.clear();
|
|
149
|
+
toolCache.clear();
|
|
92
150
|
}
|
|
93
151
|
|
|
94
|
-
module.exports = { composePrompt, clearCache, _test: { applyVariables, sortSnippets } };
|
|
152
|
+
module.exports = { composePrompt, resolveTools, clearCache, _test: { applyVariables, sortSnippets } };
|