@nexus-cortex/core 4.124.43 → 4.124.45
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/.env.defaults +184 -0
- package/dist/adapters/GatewayTranslationLayer.d.ts.map +1 -1
- package/dist/adapters/GatewayTranslationLayer.js +14 -1
- package/dist/adapters/GatewayTranslationLayer.js.map +1 -1
- package/dist/adapters/ServerSideToolDetection.d.ts.map +1 -1
- package/dist/adapters/ServerSideToolDetection.js +5 -1
- package/dist/adapters/ServerSideToolDetection.js.map +1 -1
- package/dist/config/SettingsLoader.d.ts +3 -1
- package/dist/config/SettingsLoader.d.ts.map +1 -1
- package/dist/config/SettingsLoader.js +18 -4
- package/dist/config/SettingsLoader.js.map +1 -1
- package/dist/config/SettingsSchema.d.ts +1 -0
- package/dist/config/SettingsSchema.d.ts.map +1 -1
- package/dist/config/SettingsSchema.js +9 -0
- package/dist/config/SettingsSchema.js.map +1 -1
- package/dist/config/effectiveConfig.d.ts +1 -1
- package/dist/config/effectiveConfig.d.ts.map +1 -1
- package/dist/config/effectiveConfig.js +21 -1
- package/dist/config/effectiveConfig.js.map +1 -1
- package/dist/config/interactiveProfile.d.ts +86 -0
- package/dist/config/interactiveProfile.d.ts.map +1 -0
- package/dist/config/interactiveProfile.js +114 -0
- package/dist/config/interactiveProfile.js.map +1 -0
- package/dist/middleware/HelperModelMiddleware.d.ts +10 -0
- package/dist/middleware/HelperModelMiddleware.d.ts.map +1 -1
- package/dist/middleware/HelperModelMiddleware.js +48 -5
- package/dist/middleware/HelperModelMiddleware.js.map +1 -1
- package/dist/middleware/SystemMessageMiddleware.d.ts.map +1 -1
- package/dist/middleware/SystemMessageMiddleware.js +4 -2
- package/dist/middleware/SystemMessageMiddleware.js.map +1 -1
- package/dist/middleware/helpers/helperProviderMatch.d.ts +40 -0
- package/dist/middleware/helpers/helperProviderMatch.d.ts.map +1 -0
- package/dist/middleware/helpers/helperProviderMatch.js +50 -0
- package/dist/middleware/helpers/helperProviderMatch.js.map +1 -0
- package/dist/orchestrator/APIClient.d.ts.map +1 -1
- package/dist/orchestrator/APIClient.js +92 -13
- package/dist/orchestrator/APIClient.js.map +1 -1
- package/dist/orchestrator/CortexOrchestrator.d.ts +22 -0
- package/dist/orchestrator/CortexOrchestrator.d.ts.map +1 -1
- package/dist/orchestrator/CortexOrchestrator.js +211 -82
- package/dist/orchestrator/CortexOrchestrator.js.map +1 -1
- package/dist/orchestrator/OrchestratorFactory.d.ts.map +1 -1
- package/dist/orchestrator/OrchestratorFactory.js +10 -0
- package/dist/orchestrator/OrchestratorFactory.js.map +1 -1
- package/dist/orchestrator/appendOnlyHistory.d.ts +39 -0
- package/dist/orchestrator/appendOnlyHistory.d.ts.map +1 -0
- package/dist/orchestrator/appendOnlyHistory.js +75 -0
- package/dist/orchestrator/appendOnlyHistory.js.map +1 -0
- package/dist/orchestrator/transportCacheFixes.d.ts +22 -0
- package/dist/orchestrator/transportCacheFixes.d.ts.map +1 -0
- package/dist/orchestrator/transportCacheFixes.js +114 -0
- package/dist/orchestrator/transportCacheFixes.js.map +1 -0
- package/dist/orchestrator/transportFixes.d.ts +55 -0
- package/dist/orchestrator/transportFixes.d.ts.map +1 -0
- package/dist/orchestrator/transportFixes.js +182 -0
- package/dist/orchestrator/transportFixes.js.map +1 -0
- package/dist/orchestrator/wallGuard.d.ts +3 -1
- package/dist/orchestrator/wallGuard.d.ts.map +1 -1
- package/dist/orchestrator/wallGuard.js +15 -2
- package/dist/orchestrator/wallGuard.js.map +1 -1
- package/dist/system-messages/promptPresets.d.ts +29 -1
- package/dist/system-messages/promptPresets.d.ts.map +1 -1
- package/dist/system-messages/promptPresets.js +44 -2
- package/dist/system-messages/promptPresets.js.map +1 -1
- package/dist/tools/ClientSideToolFilter.d.ts +9 -2
- package/dist/tools/ClientSideToolFilter.d.ts.map +1 -1
- package/dist/tools/ClientSideToolFilter.js +26 -3
- package/dist/tools/ClientSideToolFilter.js.map +1 -1
- package/dist/training/DecisionStore.d.ts +1 -1
- package/dist/training/DecisionStore.d.ts.map +1 -1
- package/dist/training/DecisionStore.js.map +1 -1
- package/package.json +3 -3
|
@@ -19,6 +19,8 @@ import { GoogleGenAI } from '@google/genai';
|
|
|
19
19
|
import { v4 as uuidv4 } from 'uuid';
|
|
20
20
|
import { assertCompletionBody } from './completionBodyGuard.js';
|
|
21
21
|
import { parseHFCompletion, normalizeToolCallArguments } from '../models/hfSpace/normalize.js';
|
|
22
|
+
import { isResponsesInlineRemindersEnabled, inlineRemindersForResponses, isResponsesStopReasonEnabled, isAnthropicHistoryCacheEnabled, applyAnthropicHistoryCache, countAnthropicBreakpoints, } from './transportFixes.js';
|
|
23
|
+
import { isGeminiSystemFixEnabled, isOpenAICacheKeyEnabled, isStreamUsageEnabled, applyAnthropicCacheLevers, streamFinalUsage, } from './transportCacheFixes.js';
|
|
22
24
|
import { anthropicCredentialService, CredentialError } from '../config/AnthropicCredentialService.js';
|
|
23
25
|
/**
|
|
24
26
|
* Anthropic families on the adaptive-thinking-only request surface — sending
|
|
@@ -353,6 +355,15 @@ export class APIClient {
|
|
|
353
355
|
}
|
|
354
356
|
this.applyToolChoice(anthropicRequest, request, 'messages'); // §13-B1 forced tool_choice
|
|
355
357
|
}
|
|
358
|
+
// R218 (DARK, CORTEX_ANTHROPIC_HISTORY_CACHE=on): rolling message-level breakpoints so the conversation
|
|
359
|
+
// history is cached, within the 4-breakpoint cap (system + last tool counted). Anthropic only.
|
|
360
|
+
if (enableCaching && isAnthropicHistoryCacheEnabled()) {
|
|
361
|
+
anthropicRequest.messages = applyAnthropicHistoryCache(anthropicRequest.messages, countAnthropicBreakpoints({ system: anthropicRequest.system, tools: anthropicRequest.tools })).messages;
|
|
362
|
+
}
|
|
363
|
+
// R225 (DARK): CORTEX_ANTHROPIC_AUTO_CACHE top-level automatic cache_control (free slot only) +
|
|
364
|
+
// CORTEX_ANTHROPIC_CACHE_TTL=1h on every marker. Anthropic only; no-op with both flags off.
|
|
365
|
+
if (enableCaching)
|
|
366
|
+
applyAnthropicCacheLevers(anthropicRequest);
|
|
356
367
|
// Phase 2.8: Enable extended thinking for Claude 4+ models with reasoning support
|
|
357
368
|
// Requires beta header: anthropic-beta: interleaved-thinking-2025-05-14
|
|
358
369
|
// Skip if disableThinking option is set (used for continuation requests)
|
|
@@ -778,6 +789,16 @@ export class APIClient {
|
|
|
778
789
|
chatRequest.tools = request.tools;
|
|
779
790
|
this.applyToolChoice(chatRequest, request, 'chat/completions'); // §13-B1 forced tool_choice
|
|
780
791
|
}
|
|
792
|
+
// R225 (DARK, CORTEX_OPENAI_CACHE_KEY): OpenAI routes same-key requests to the same prompt cache.
|
|
793
|
+
// OpenAI provider only (other chat/completions providers may reject the unknown field).
|
|
794
|
+
if (isOpenAICacheKeyEnabled() && modelConfig.provider === 'openai' && request.conversationId) {
|
|
795
|
+
chatRequest.prompt_cache_key = request.conversationId;
|
|
796
|
+
}
|
|
797
|
+
// R224a (DARK, CORTEX_STREAM_USAGE): ask for the final usage chunk on streaming requests (otherwise the
|
|
798
|
+
// reassembled message reports zeros). Body-level, after the prefix — cache-neutral.
|
|
799
|
+
if (opts.stream && isStreamUsageEnabled()) {
|
|
800
|
+
chatRequest.stream_options = { include_usage: true };
|
|
801
|
+
}
|
|
781
802
|
this.logChatCompletionsPayload(chatRequest, request.modelId, opts.stream);
|
|
782
803
|
return { client, chatRequest };
|
|
783
804
|
}
|
|
@@ -982,7 +1003,12 @@ export class APIClient {
|
|
|
982
1003
|
//
|
|
983
1004
|
// Extract <system-reminder> content from user messages into `instructions` parameter.
|
|
984
1005
|
// This lets the Responses API cache system context separately from conversation content.
|
|
985
|
-
|
|
1006
|
+
// R215 (DARK, CORTEX_RESPONSES_INLINE_REMINDERS=on): keep reminders IN PLACE as user input_text items
|
|
1007
|
+
// (xAI never receives `instructions`; OpenAI lost their position after the tool output). R63 system
|
|
1008
|
+
// delivery below is unchanged — `instructions` then carries only the static system prompt.
|
|
1009
|
+
const { instructions, cleanedItems: inputItems } = isResponsesInlineRemindersEnabled()
|
|
1010
|
+
? { instructions: undefined, cleanedItems: inlineRemindersForResponses(request.messages) }
|
|
1011
|
+
: this.extractSystemRemindersForResponsesAPI(request.messages);
|
|
986
1012
|
// Check reasoning support
|
|
987
1013
|
const supportsReasoning = modelConfig.reasoning?.supported;
|
|
988
1014
|
const { disableThinking, reasoningEffort, ...apiParameters } = request.parameters;
|
|
@@ -1043,6 +1069,10 @@ export class APIClient {
|
|
|
1043
1069
|
// opt-in ZDR mode: "DESIGN NOTE — stateless ZDR mode" in
|
|
1044
1070
|
// ResponsesAPIAdapter.ts (adapters/).
|
|
1045
1071
|
}
|
|
1072
|
+
// R225 (DARK, CORTEX_OPENAI_CACHE_KEY): the same session-scoped cache routing key for OpenAI Responses.
|
|
1073
|
+
if (isOpenAICacheKeyEnabled() && modelConfig.provider?.toLowerCase() === 'openai' && request.conversationId) {
|
|
1074
|
+
responsesRequest.prompt_cache_key = request.conversationId;
|
|
1075
|
+
}
|
|
1046
1076
|
// Set system context as instructions (enables provider-side caching).
|
|
1047
1077
|
// R63: request.systemMessage (the R28 static system prompt) was previously
|
|
1048
1078
|
// dropped on this path — only <system-reminder> text mined from user
|
|
@@ -1154,6 +1184,12 @@ export class APIClient {
|
|
|
1154
1184
|
if (request.tools && request.tools.length > 0) {
|
|
1155
1185
|
return this.sendGenerateContentHTTP(request, modelConfig, apiKey);
|
|
1156
1186
|
}
|
|
1187
|
+
// R229 (DARK, CORTEX_GEMINI_SYSTEM_FIX): the @google/generative-ai SDK (v0.2.1, v1 endpoint) has no
|
|
1188
|
+
// systemInstruction support, so a request carrying a system prompt goes through the v1beta REST builder,
|
|
1189
|
+
// which sends it as system_instruction.
|
|
1190
|
+
if (isGeminiSystemFixEnabled() && request.systemMessage) {
|
|
1191
|
+
return this.sendGenerateContentHTTP(request, modelConfig, apiKey);
|
|
1192
|
+
}
|
|
1157
1193
|
// For non-tool requests, use SDK as before
|
|
1158
1194
|
if (!this.googleClient) {
|
|
1159
1195
|
this.googleClient = new GoogleGenerativeAI(apiKey);
|
|
@@ -1201,6 +1237,11 @@ export class APIClient {
|
|
|
1201
1237
|
contents: request.messages,
|
|
1202
1238
|
generation_config: generationConfig // Use the nested object directly
|
|
1203
1239
|
};
|
|
1240
|
+
// R229 (DARK, CORTEX_GEMINI_SYSTEM_FIX): deliver the system prompt (the streaming HTTP builder always did;
|
|
1241
|
+
// this non-streaming builder never did). Same snake_case shape as streamGenerateContentHTTP.
|
|
1242
|
+
if (isGeminiSystemFixEnabled() && request.systemMessage) {
|
|
1243
|
+
requestBody.system_instruction = { parts: [{ text: request.systemMessage }] };
|
|
1244
|
+
}
|
|
1204
1245
|
// Add tools if present
|
|
1205
1246
|
if (request.tools && request.tools.length > 0) {
|
|
1206
1247
|
// REST API uses snake_case "function_declarations", not camelCase "functionDeclarations"
|
|
@@ -1338,6 +1379,13 @@ export class APIClient {
|
|
|
1338
1379
|
}
|
|
1339
1380
|
this.applyToolChoice(anthropicRequest, request, 'messages'); // §13-B1 forced tool_choice
|
|
1340
1381
|
}
|
|
1382
|
+
// R218 (DARK): rolling message-level cache breakpoints — mirrors sendAnthropicMessagesAPI.
|
|
1383
|
+
if (enableCaching && isAnthropicHistoryCacheEnabled()) {
|
|
1384
|
+
anthropicRequest.messages = applyAnthropicHistoryCache(anthropicRequest.messages, countAnthropicBreakpoints({ system: anthropicRequest.system, tools: anthropicRequest.tools })).messages;
|
|
1385
|
+
}
|
|
1386
|
+
// R225 (DARK): automatic cache_control + 1h TTL — mirrors sendAnthropicMessagesAPI.
|
|
1387
|
+
if (enableCaching)
|
|
1388
|
+
applyAnthropicCacheLevers(anthropicRequest);
|
|
1341
1389
|
// Phase 2.8: Enable extended thinking for Claude 4+ models with reasoning support
|
|
1342
1390
|
// Requires beta header: anthropic-beta: interleaved-thinking-2025-05-14
|
|
1343
1391
|
// Skip if disableThinking option is set (used for continuation requests)
|
|
@@ -1966,6 +2014,9 @@ export class APIClient {
|
|
|
1966
2014
|
// R153 (2026-09-16): keep the provider's LAST non-null finish_reason so a `length` cutoff survives reassembly
|
|
1967
2015
|
// (the empty-response classifier keys `truncated` on it; the old hardcode reported every text turn as `stop`).
|
|
1968
2016
|
let lastFinishReason = null;
|
|
2017
|
+
// R224a (DARK, CORTEX_STREAM_USAGE): the provider's final usage chunk (choices: []) when requested.
|
|
2018
|
+
const captureStreamUsage = isStreamUsageEnabled();
|
|
2019
|
+
let streamUsage = null;
|
|
1969
2020
|
// Capture this context before entering generator
|
|
1970
2021
|
const self = this;
|
|
1971
2022
|
// Create async generator that both yields chunks AND accumulates final message
|
|
@@ -1979,7 +2030,9 @@ export class APIClient {
|
|
|
1979
2030
|
if (!firstChunk)
|
|
1980
2031
|
firstChunk = chunk;
|
|
1981
2032
|
chunkCount++;
|
|
1982
|
-
|
|
2033
|
+
if (captureStreamUsage && chunk?.usage)
|
|
2034
|
+
streamUsage = chunk.usage;
|
|
2035
|
+
const delta = chunk.choices?.[0]?.delta;
|
|
1983
2036
|
// Debug: Log first few chunks to see what fields are present
|
|
1984
2037
|
if ((process.env.DEBUG === 'true' || process.env.DEBUG_THINKING === 'true') && chunkCount <= 3) {
|
|
1985
2038
|
console.log(`[DEBUG APIClient] Chunk ${chunkCount} delta keys:`, delta ? Object.keys(delta) : 'null');
|
|
@@ -2030,7 +2083,7 @@ export class APIClient {
|
|
|
2030
2083
|
}
|
|
2031
2084
|
}
|
|
2032
2085
|
// Check if finish_reason indicates tool_calls completion (or length-truncated tool call)
|
|
2033
|
-
const finishReason = chunk.choices[0]?.finish_reason;
|
|
2086
|
+
const finishReason = chunk.choices?.[0]?.finish_reason;
|
|
2034
2087
|
if (finishReason)
|
|
2035
2088
|
lastFinishReason = String(finishReason);
|
|
2036
2089
|
if ((finishReason === 'tool_calls' || finishReason === 'length') && accumulatedToolCalls.size > 0) {
|
|
@@ -2096,11 +2149,7 @@ export class APIClient {
|
|
|
2096
2149
|
// ('length' = output cap hit) instead of a synthetic 'stop'.
|
|
2097
2150
|
finish_reason: finalToolCalls.length > 0 ? 'tool_calls' : (lastFinishReason ?? 'stop')
|
|
2098
2151
|
}],
|
|
2099
|
-
usage:
|
|
2100
|
-
prompt_tokens: 0,
|
|
2101
|
-
completion_tokens: 0,
|
|
2102
|
-
total_tokens: 0
|
|
2103
|
-
}
|
|
2152
|
+
usage: streamFinalUsage(streamUsage)
|
|
2104
2153
|
});
|
|
2105
2154
|
}();
|
|
2106
2155
|
return {
|
|
@@ -2125,7 +2174,10 @@ export class APIClient {
|
|
|
2125
2174
|
// Re-wrapping them would strip tool results and function calls, breaking the tool loop.
|
|
2126
2175
|
//
|
|
2127
2176
|
// Extract <system-reminder> content from user messages into `instructions` parameter.
|
|
2128
|
-
|
|
2177
|
+
// R215 (DARK): CORTEX_RESPONSES_INLINE_REMINDERS=on keeps them in place (mirrors sendResponsesAPI).
|
|
2178
|
+
const { instructions, cleanedItems: inputItems } = isResponsesInlineRemindersEnabled()
|
|
2179
|
+
? { instructions: undefined, cleanedItems: inlineRemindersForResponses(request.messages) }
|
|
2180
|
+
: this.extractSystemRemindersForResponsesAPI(request.messages);
|
|
2129
2181
|
// Accumulate content from stream
|
|
2130
2182
|
let fullContent = '';
|
|
2131
2183
|
let fullReasoningContent = '';
|
|
@@ -2197,6 +2249,10 @@ export class APIClient {
|
|
|
2197
2249
|
responsesRequest.prompt_cache_key = request.conversationId;
|
|
2198
2250
|
}
|
|
2199
2251
|
}
|
|
2252
|
+
// R225 (DARK, CORTEX_OPENAI_CACHE_KEY): mirrors sendResponsesAPI.
|
|
2253
|
+
if (isOpenAICacheKeyEnabled() && modelConfig.provider?.toLowerCase() === 'openai' && request.conversationId) {
|
|
2254
|
+
responsesRequest.prompt_cache_key = request.conversationId;
|
|
2255
|
+
}
|
|
2200
2256
|
// Set system context as instructions (enables provider-side caching).
|
|
2201
2257
|
// R63: merge the R28 static system prompt (previously dropped on this
|
|
2202
2258
|
// path) ahead of reminders mined from user messages; XAI gets it as a
|
|
@@ -2427,7 +2483,12 @@ export class APIClient {
|
|
|
2427
2483
|
prompt_tokens: 0,
|
|
2428
2484
|
completion_tokens: 0,
|
|
2429
2485
|
total_tokens: 0
|
|
2430
|
-
}
|
|
2486
|
+
},
|
|
2487
|
+
// R216 (DARK, CORTEX_RESPONSES_STOP_REASON=on): carry the terminal event's status +
|
|
2488
|
+
// incomplete_details (response.completed / response.incomplete) so extractStopReason sees truncation.
|
|
2489
|
+
...(isResponsesStopReasonEnabled() && typeof finalResponse?.status === 'string'
|
|
2490
|
+
? { status: finalResponse.status, incomplete_details: finalResponse.incomplete_details ?? null }
|
|
2491
|
+
: {})
|
|
2431
2492
|
});
|
|
2432
2493
|
}();
|
|
2433
2494
|
return {
|
|
@@ -2452,6 +2513,11 @@ export class APIClient {
|
|
|
2452
2513
|
if (request.tools && request.tools.length > 0) {
|
|
2453
2514
|
return this.streamGenerateContentHTTP(request, modelConfig, apiKey);
|
|
2454
2515
|
}
|
|
2516
|
+
// R229 (DARK, CORTEX_GEMINI_SYSTEM_FIX): the old SDK cannot send a system prompt — use the v1beta REST
|
|
2517
|
+
// streaming builder (already sends system_instruction) whenever one is present.
|
|
2518
|
+
if (isGeminiSystemFixEnabled() && request.systemMessage) {
|
|
2519
|
+
return this.streamGenerateContentHTTP(request, modelConfig, apiKey);
|
|
2520
|
+
}
|
|
2455
2521
|
// For non-tool requests, use SDK streaming
|
|
2456
2522
|
if (!this.googleClient) {
|
|
2457
2523
|
this.googleClient = new GoogleGenerativeAI(apiKey);
|
|
@@ -2820,7 +2886,14 @@ export class APIClient {
|
|
|
2820
2886
|
config
|
|
2821
2887
|
};
|
|
2822
2888
|
if (request.systemMessage) {
|
|
2823
|
-
|
|
2889
|
+
if (isGeminiSystemFixEnabled()) {
|
|
2890
|
+
// R229 (DARK): @google/genai reads the system prompt ONLY from config.systemInstruction
|
|
2891
|
+
// (GenerateContentParameters = {model, contents, config}); a top-level field is dropped.
|
|
2892
|
+
config.systemInstruction = request.systemMessage;
|
|
2893
|
+
}
|
|
2894
|
+
else {
|
|
2895
|
+
sdkRequest.systemInstruction = request.systemMessage;
|
|
2896
|
+
}
|
|
2824
2897
|
}
|
|
2825
2898
|
if (process.env.DEBUG === 'true') {
|
|
2826
2899
|
console.log(`[DEBUG APIClient SDK] Non-streaming request for model: ${modelId}`);
|
|
@@ -2917,9 +2990,15 @@ export class APIClient {
|
|
|
2917
2990
|
contents: request.messages,
|
|
2918
2991
|
config // Config contains both generation params and tools
|
|
2919
2992
|
};
|
|
2920
|
-
// Add system instruction if present
|
|
2993
|
+
// Add system instruction if present. Legacy: top level (the SDK DROPS it — GenerateContentParameters =
|
|
2994
|
+
// {model, contents, config}). R229 (DARK, CORTEX_GEMINI_SYSTEM_FIX): config.systemInstruction.
|
|
2921
2995
|
if (request.systemMessage) {
|
|
2922
|
-
|
|
2996
|
+
if (isGeminiSystemFixEnabled()) {
|
|
2997
|
+
config.systemInstruction = request.systemMessage;
|
|
2998
|
+
}
|
|
2999
|
+
else {
|
|
3000
|
+
sdkRequest.systemInstruction = request.systemMessage;
|
|
3001
|
+
}
|
|
2923
3002
|
}
|
|
2924
3003
|
if (process.env.DEBUG === 'true') {
|
|
2925
3004
|
console.log(`[DEBUG APIClient SDK] Using model: ${modelId}`);
|