@aj-archipelago/cortex 1.3.62 → 1.3.63
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/.github/workflows/cortex-file-handler-test.yml +61 -0
- package/README.md +31 -7
- package/config/default.example.json +15 -0
- package/config.js +133 -12
- package/helper-apps/cortex-autogen2/DigiCertGlobalRootCA.crt.pem +22 -0
- package/helper-apps/cortex-autogen2/Dockerfile +31 -0
- package/helper-apps/cortex-autogen2/Dockerfile.worker +41 -0
- package/helper-apps/cortex-autogen2/README.md +183 -0
- package/helper-apps/cortex-autogen2/__init__.py +1 -0
- package/helper-apps/cortex-autogen2/agents.py +131 -0
- package/helper-apps/cortex-autogen2/docker-compose.yml +20 -0
- package/helper-apps/cortex-autogen2/function_app.py +55 -0
- package/helper-apps/cortex-autogen2/host.json +15 -0
- package/helper-apps/cortex-autogen2/main.py +126 -0
- package/helper-apps/cortex-autogen2/poetry.lock +3652 -0
- package/helper-apps/cortex-autogen2/pyproject.toml +36 -0
- package/helper-apps/cortex-autogen2/requirements.txt +20 -0
- package/helper-apps/cortex-autogen2/send_task.py +105 -0
- package/helper-apps/cortex-autogen2/services/__init__.py +1 -0
- package/helper-apps/cortex-autogen2/services/azure_queue.py +85 -0
- package/helper-apps/cortex-autogen2/services/redis_publisher.py +153 -0
- package/helper-apps/cortex-autogen2/task_processor.py +488 -0
- package/helper-apps/cortex-autogen2/tools/__init__.py +24 -0
- package/helper-apps/cortex-autogen2/tools/azure_blob_tools.py +175 -0
- package/helper-apps/cortex-autogen2/tools/azure_foundry_agents.py +601 -0
- package/helper-apps/cortex-autogen2/tools/coding_tools.py +72 -0
- package/helper-apps/cortex-autogen2/tools/download_tools.py +48 -0
- package/helper-apps/cortex-autogen2/tools/file_tools.py +545 -0
- package/helper-apps/cortex-autogen2/tools/search_tools.py +646 -0
- package/helper-apps/cortex-azure-cleaner/README.md +36 -0
- package/helper-apps/cortex-file-converter/README.md +93 -0
- package/helper-apps/cortex-file-converter/key_to_pdf.py +104 -0
- package/helper-apps/cortex-file-converter/list_blob_extensions.py +89 -0
- package/helper-apps/cortex-file-converter/process_azure_keynotes.py +181 -0
- package/helper-apps/cortex-file-converter/requirements.txt +1 -0
- package/helper-apps/cortex-file-handler/.env.test.azure.ci +7 -0
- package/helper-apps/cortex-file-handler/.env.test.azure.sample +1 -1
- package/helper-apps/cortex-file-handler/.env.test.gcs.ci +10 -0
- package/helper-apps/cortex-file-handler/.env.test.gcs.sample +2 -2
- package/helper-apps/cortex-file-handler/INTERFACE.md +41 -0
- package/helper-apps/cortex-file-handler/package.json +1 -1
- package/helper-apps/cortex-file-handler/scripts/setup-azure-container.js +41 -17
- package/helper-apps/cortex-file-handler/scripts/setup-test-containers.js +30 -15
- package/helper-apps/cortex-file-handler/scripts/test-azure.sh +32 -6
- package/helper-apps/cortex-file-handler/scripts/test-gcs.sh +24 -2
- package/helper-apps/cortex-file-handler/scripts/validate-env.js +128 -0
- package/helper-apps/cortex-file-handler/src/blobHandler.js +161 -51
- package/helper-apps/cortex-file-handler/src/constants.js +3 -0
- package/helper-apps/cortex-file-handler/src/fileChunker.js +10 -8
- package/helper-apps/cortex-file-handler/src/index.js +116 -9
- package/helper-apps/cortex-file-handler/src/redis.js +61 -1
- package/helper-apps/cortex-file-handler/src/services/ConversionService.js +11 -8
- package/helper-apps/cortex-file-handler/src/services/FileConversionService.js +2 -2
- package/helper-apps/cortex-file-handler/src/services/storage/AzureStorageProvider.js +88 -6
- package/helper-apps/cortex-file-handler/src/services/storage/GCSStorageProvider.js +58 -0
- package/helper-apps/cortex-file-handler/src/services/storage/StorageFactory.js +25 -5
- package/helper-apps/cortex-file-handler/src/services/storage/StorageProvider.js +9 -0
- package/helper-apps/cortex-file-handler/src/services/storage/StorageService.js +120 -16
- package/helper-apps/cortex-file-handler/src/start.js +27 -17
- package/helper-apps/cortex-file-handler/tests/FileConversionService.test.js +52 -1
- package/helper-apps/cortex-file-handler/tests/blobHandler.test.js +40 -0
- package/helper-apps/cortex-file-handler/tests/checkHashShortLived.test.js +553 -0
- package/helper-apps/cortex-file-handler/tests/cleanup.test.js +46 -52
- package/helper-apps/cortex-file-handler/tests/containerConversionFlow.test.js +451 -0
- package/helper-apps/cortex-file-handler/tests/containerNameParsing.test.js +229 -0
- package/helper-apps/cortex-file-handler/tests/containerParameterFlow.test.js +392 -0
- package/helper-apps/cortex-file-handler/tests/conversionResilience.test.js +7 -2
- package/helper-apps/cortex-file-handler/tests/deleteOperations.test.js +348 -0
- package/helper-apps/cortex-file-handler/tests/fileChunker.test.js +23 -2
- package/helper-apps/cortex-file-handler/tests/fileUpload.test.js +11 -5
- package/helper-apps/cortex-file-handler/tests/getOperations.test.js +58 -24
- package/helper-apps/cortex-file-handler/tests/postOperations.test.js +11 -4
- package/helper-apps/cortex-file-handler/tests/shortLivedUrlConversion.test.js +225 -0
- package/helper-apps/cortex-file-handler/tests/start.test.js +8 -12
- package/helper-apps/cortex-file-handler/tests/storage/StorageFactory.test.js +80 -0
- package/helper-apps/cortex-file-handler/tests/storage/StorageService.test.js +388 -22
- package/helper-apps/cortex-file-handler/tests/testUtils.helper.js +74 -0
- package/lib/cortexResponse.js +153 -0
- package/lib/entityConstants.js +21 -3
- package/lib/logger.js +21 -4
- package/lib/pathwayTools.js +28 -9
- package/lib/util.js +49 -0
- package/package.json +1 -1
- package/pathways/basePathway.js +1 -0
- package/pathways/bing_afagent.js +54 -1
- package/pathways/call_tools.js +2 -3
- package/pathways/chat_jarvis.js +1 -1
- package/pathways/google_cse.js +27 -0
- package/pathways/grok_live_search.js +18 -0
- package/pathways/system/entity/memory/sys_memory_lookup_required.js +1 -0
- package/pathways/system/entity/memory/sys_memory_required.js +1 -0
- package/pathways/system/entity/memory/sys_search_memory.js +1 -0
- package/pathways/system/entity/sys_entity_agent.js +56 -4
- package/pathways/system/entity/sys_generator_quick.js +1 -0
- package/pathways/system/entity/tools/sys_tool_bing_search_afagent.js +26 -0
- package/pathways/system/entity/tools/sys_tool_google_search.js +141 -0
- package/pathways/system/entity/tools/sys_tool_grok_x_search.js +237 -0
- package/pathways/system/entity/tools/sys_tool_image.js +1 -1
- package/pathways/system/rest_streaming/sys_claude_37_sonnet.js +21 -0
- package/pathways/system/rest_streaming/sys_claude_41_opus.js +21 -0
- package/pathways/system/rest_streaming/sys_claude_4_sonnet.js +21 -0
- package/pathways/system/rest_streaming/sys_google_gemini_25_flash.js +25 -0
- package/pathways/system/rest_streaming/{sys_google_gemini_chat.js → sys_google_gemini_25_pro.js} +6 -4
- package/pathways/system/rest_streaming/sys_grok_4.js +23 -0
- package/pathways/system/rest_streaming/sys_grok_4_fast_non_reasoning.js +23 -0
- package/pathways/system/rest_streaming/sys_grok_4_fast_reasoning.js +23 -0
- package/pathways/system/rest_streaming/sys_openai_chat.js +3 -0
- package/pathways/system/rest_streaming/sys_openai_chat_gpt41.js +22 -0
- package/pathways/system/rest_streaming/sys_openai_chat_gpt41_mini.js +21 -0
- package/pathways/system/rest_streaming/sys_openai_chat_gpt41_nano.js +21 -0
- package/pathways/system/rest_streaming/{sys_claude_35_sonnet.js → sys_openai_chat_gpt4_omni.js} +6 -4
- package/pathways/system/rest_streaming/sys_openai_chat_gpt4_omni_mini.js +21 -0
- package/pathways/system/rest_streaming/{sys_claude_3_haiku.js → sys_openai_chat_gpt5.js} +7 -5
- package/pathways/system/rest_streaming/sys_openai_chat_gpt5_chat.js +21 -0
- package/pathways/system/rest_streaming/sys_openai_chat_gpt5_mini.js +21 -0
- package/pathways/system/rest_streaming/sys_openai_chat_gpt5_nano.js +21 -0
- package/pathways/system/rest_streaming/{sys_openai_chat_o1.js → sys_openai_chat_o3.js} +6 -3
- package/pathways/system/rest_streaming/sys_openai_chat_o3_mini.js +3 -0
- package/pathways/system/workspaces/run_workspace_prompt.js +99 -0
- package/pathways/vision.js +1 -1
- package/server/graphql.js +1 -1
- package/server/modelExecutor.js +8 -0
- package/server/pathwayResolver.js +166 -16
- package/server/pathwayResponseParser.js +16 -8
- package/server/plugins/azureFoundryAgentsPlugin.js +1 -1
- package/server/plugins/claude3VertexPlugin.js +193 -45
- package/server/plugins/gemini15ChatPlugin.js +21 -0
- package/server/plugins/gemini15VisionPlugin.js +360 -0
- package/server/plugins/googleCsePlugin.js +94 -0
- package/server/plugins/grokVisionPlugin.js +365 -0
- package/server/plugins/modelPlugin.js +3 -1
- package/server/plugins/openAiChatPlugin.js +106 -13
- package/server/plugins/openAiVisionPlugin.js +42 -30
- package/server/resolver.js +28 -4
- package/server/rest.js +270 -53
- package/server/typeDef.js +1 -0
- package/tests/{mocks.js → helpers/mocks.js} +5 -2
- package/tests/{server.js → helpers/server.js} +2 -2
- package/tests/helpers/sseAssert.js +23 -0
- package/tests/helpers/sseClient.js +73 -0
- package/tests/helpers/subscriptionAssert.js +11 -0
- package/tests/helpers/subscriptions.js +113 -0
- package/tests/{sublong.srt → integration/features/translate/sublong.srt} +4543 -4543
- package/tests/integration/features/translate/translate_chunking_stream.test.js +100 -0
- package/tests/{translate_srt.test.js → integration/features/translate/translate_srt.test.js} +2 -2
- package/tests/integration/graphql/async/stream/agentic.test.js +477 -0
- package/tests/integration/graphql/async/stream/subscription_streaming.test.js +62 -0
- package/tests/integration/graphql/async/stream/sys_entity_start_streaming.test.js +71 -0
- package/tests/integration/graphql/async/stream/vendors/claude_streaming.test.js +56 -0
- package/tests/integration/graphql/async/stream/vendors/gemini_streaming.test.js +66 -0
- package/tests/integration/graphql/async/stream/vendors/grok_streaming.test.js +56 -0
- package/tests/integration/graphql/async/stream/vendors/openai_streaming.test.js +72 -0
- package/tests/integration/graphql/features/google/sysToolGoogleSearch.test.js +96 -0
- package/tests/integration/graphql/features/grok/grok.test.js +688 -0
- package/tests/integration/graphql/features/grok/grok_x_search_tool.test.js +354 -0
- package/tests/{main.test.js → integration/graphql/features/main.test.js} +1 -1
- package/tests/{call_tools.test.js → integration/graphql/features/tools/call_tools.test.js} +2 -2
- package/tests/{vision.test.js → integration/graphql/features/vision/vision.test.js} +1 -1
- package/tests/integration/graphql/subscriptions/connection.test.js +26 -0
- package/tests/{openai_api.test.js → integration/rest/oai/openai_api.test.js} +63 -238
- package/tests/integration/rest/oai/tool_calling_api.test.js +343 -0
- package/tests/integration/rest/oai/tool_calling_streaming.test.js +85 -0
- package/tests/integration/rest/vendors/claude_streaming.test.js +47 -0
- package/tests/integration/rest/vendors/claude_tool_calling_streaming.test.js +75 -0
- package/tests/integration/rest/vendors/gemini_streaming.test.js +47 -0
- package/tests/integration/rest/vendors/gemini_tool_calling_streaming.test.js +75 -0
- package/tests/integration/rest/vendors/grok_streaming.test.js +55 -0
- package/tests/integration/rest/vendors/grok_tool_calling_streaming.test.js +75 -0
- package/tests/{azureAuthTokenHelper.test.js → unit/core/azureAuthTokenHelper.test.js} +1 -1
- package/tests/{chunkfunction.test.js → unit/core/chunkfunction.test.js} +2 -2
- package/tests/{config.test.js → unit/core/config.test.js} +3 -3
- package/tests/{encodeCache.test.js → unit/core/encodeCache.test.js} +1 -1
- package/tests/{fastLruCache.test.js → unit/core/fastLruCache.test.js} +1 -1
- package/tests/{handleBars.test.js → unit/core/handleBars.test.js} +1 -1
- package/tests/{memoryfunction.test.js → unit/core/memoryfunction.test.js} +2 -2
- package/tests/unit/core/mergeResolver.test.js +952 -0
- package/tests/{parser.test.js → unit/core/parser.test.js} +3 -3
- package/tests/unit/core/pathwayResolver.test.js +187 -0
- package/tests/{requestMonitor.test.js → unit/core/requestMonitor.test.js} +1 -1
- package/tests/{requestMonitorDurationEstimator.test.js → unit/core/requestMonitorDurationEstimator.test.js} +1 -1
- package/tests/{truncateMessages.test.js → unit/core/truncateMessages.test.js} +3 -3
- package/tests/{util.test.js → unit/core/util.test.js} +1 -1
- package/tests/{apptekTranslatePlugin.test.js → unit/plugins/apptekTranslatePlugin.test.js} +3 -3
- package/tests/{azureFoundryAgents.test.js → unit/plugins/azureFoundryAgents.test.js} +136 -1
- package/tests/{claude3VertexPlugin.test.js → unit/plugins/claude3VertexPlugin.test.js} +32 -10
- package/tests/{claude3VertexToolConversion.test.js → unit/plugins/claude3VertexToolConversion.test.js} +3 -3
- package/tests/unit/plugins/googleCsePlugin.test.js +111 -0
- package/tests/unit/plugins/grokVisionPlugin.test.js +1392 -0
- package/tests/{modelPlugin.test.js → unit/plugins/modelPlugin.test.js} +3 -3
- package/tests/{multimodal_conversion.test.js → unit/plugins/multimodal_conversion.test.js} +4 -4
- package/tests/{openAiChatPlugin.test.js → unit/plugins/openAiChatPlugin.test.js} +13 -4
- package/tests/{openAiToolPlugin.test.js → unit/plugins/openAiToolPlugin.test.js} +35 -27
- package/tests/{tokenHandlingTests.test.js → unit/plugins/tokenHandlingTests.test.js} +5 -5
- package/tests/{translate_apptek.test.js → unit/plugins/translate_apptek.test.js} +3 -3
- package/tests/{streaming.test.js → unit/plugins.streaming/plugin_stream_events.test.js} +19 -58
- package/helper-apps/mogrt-handler/tests/test-files/test.gif +0 -1
- package/helper-apps/mogrt-handler/tests/test-files/test.mogrt +0 -1
- package/helper-apps/mogrt-handler/tests/test-files/test.mp4 +0 -1
- package/pathways/system/rest_streaming/sys_openai_chat_gpt4.js +0 -19
- package/pathways/system/rest_streaming/sys_openai_chat_gpt4_32.js +0 -19
- package/pathways/system/rest_streaming/sys_openai_chat_gpt4_turbo.js +0 -19
- package/pathways/system/workspaces/run_claude35_sonnet.js +0 -21
- package/pathways/system/workspaces/run_claude3_haiku.js +0 -20
- package/pathways/system/workspaces/run_gpt35turbo.js +0 -20
- package/pathways/system/workspaces/run_gpt4.js +0 -20
- package/pathways/system/workspaces/run_gpt4_32.js +0 -20
- package/tests/agentic.test.js +0 -256
- package/tests/pathwayResolver.test.js +0 -78
- package/tests/subscription.test.js +0 -387
- /package/tests/{subchunk.srt → integration/features/translate/subchunk.srt} +0 -0
- /package/tests/{subhorizontal.srt → integration/features/translate/subhorizontal.srt} +0 -0
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import test from 'ava';
|
|
2
|
+
import serverFactory from '../../../../../index.js';
|
|
3
|
+
import { createWsClient, ensureWsConnection, collectSubscriptionEvents, validateProgressMessage } from '../../../../helpers/subscriptions.js';
|
|
4
|
+
|
|
5
|
+
let testServer;
|
|
6
|
+
let wsClient;
|
|
7
|
+
|
|
8
|
+
test.before(async () => {
|
|
9
|
+
process.env.CORTEX_ENABLE_REST = 'true';
|
|
10
|
+
const { server, startServer } = await serverFactory();
|
|
11
|
+
startServer && await startServer();
|
|
12
|
+
testServer = server;
|
|
13
|
+
|
|
14
|
+
wsClient = createWsClient();
|
|
15
|
+
await ensureWsConnection(wsClient);
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
test.after.always('cleanup', async () => {
|
|
19
|
+
if (wsClient) wsClient.dispose();
|
|
20
|
+
if (testServer) await testServer.stop();
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
test.serial('sys_entity_start streaming works correctly', async (t) => {
|
|
24
|
+
const response = await testServer.executeOperation({
|
|
25
|
+
query: `
|
|
26
|
+
query TestQuery($text: String!, $chatHistory: [MultiMessage]!, $stream: Boolean!) {
|
|
27
|
+
sys_entity_start(text: $text, chatHistory: $chatHistory, stream: $stream) {
|
|
28
|
+
result
|
|
29
|
+
contextId
|
|
30
|
+
tool
|
|
31
|
+
warnings
|
|
32
|
+
errors
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
`,
|
|
36
|
+
variables: {
|
|
37
|
+
text: 'Tell me about the history of Al Jazeera',
|
|
38
|
+
chatHistory: [{ role: "user", content: ["Tell me about the history of Al Jazeera"] }],
|
|
39
|
+
stream: true
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
const requestId = response.body?.singleResult?.data?.sys_entity_start?.result;
|
|
44
|
+
t.truthy(requestId);
|
|
45
|
+
|
|
46
|
+
const events = await collectSubscriptionEvents(wsClient, {
|
|
47
|
+
query: `
|
|
48
|
+
subscription OnRequestProgress($requestId: String!) {
|
|
49
|
+
requestProgress(requestIds: [$requestId]) {
|
|
50
|
+
requestId
|
|
51
|
+
progress
|
|
52
|
+
data
|
|
53
|
+
info
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
`,
|
|
57
|
+
variables: { requestId },
|
|
58
|
+
}, 30000, { requireCompletion: false, minEvents: 1 });
|
|
59
|
+
|
|
60
|
+
t.true(events.length > 0);
|
|
61
|
+
for (const event of events) {
|
|
62
|
+
const progress = event.data.requestProgress;
|
|
63
|
+
validateProgressMessage(t, progress, requestId);
|
|
64
|
+
if (progress.data) {
|
|
65
|
+
const parsed = JSON.parse(progress.data);
|
|
66
|
+
t.true(typeof parsed === 'string' || typeof parsed === 'object');
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import test from 'ava';
|
|
2
|
+
import serverFactory from '../../../../../../index.js';
|
|
3
|
+
import { createWsClient, ensureWsConnection, collectSubscriptionEvents } from '../../../../../helpers/subscriptions.js';
|
|
4
|
+
|
|
5
|
+
let testServer;
|
|
6
|
+
let wsClient;
|
|
7
|
+
|
|
8
|
+
test.before(async () => {
|
|
9
|
+
const { server, startServer } = await serverFactory();
|
|
10
|
+
startServer && await startServer();
|
|
11
|
+
testServer = server;
|
|
12
|
+
wsClient = createWsClient();
|
|
13
|
+
await ensureWsConnection(wsClient);
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
test.after.always('cleanup', async () => {
|
|
17
|
+
if (wsClient) wsClient.dispose();
|
|
18
|
+
if (testServer) await testServer.stop();
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
test('Claude vendor streaming over subscriptions emits OAI-style deltas', async (t) => {
|
|
22
|
+
const response = await testServer.executeOperation({
|
|
23
|
+
query: `
|
|
24
|
+
query($text: String!, $chatHistory: [MultiMessage]!, $stream: Boolean, $aiStyle: String) {
|
|
25
|
+
sys_entity_agent(text: $text, chatHistory: $chatHistory, stream: $stream, aiStyle: $aiStyle) {
|
|
26
|
+
result
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
`,
|
|
30
|
+
variables: {
|
|
31
|
+
text: 'Say hi',
|
|
32
|
+
chatHistory: [{ role: 'user', content: ['Say hi'] }],
|
|
33
|
+
stream: true,
|
|
34
|
+
aiStyle: 'Anthropic'
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
const requestId = response.body?.singleResult?.data?.sys_entity_agent?.result;
|
|
39
|
+
if (!requestId) {
|
|
40
|
+
t.pass('Skipping - Claude vendor model not configured');
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const events = await collectSubscriptionEvents(wsClient, {
|
|
45
|
+
query: `
|
|
46
|
+
subscription($requestId: String!) {
|
|
47
|
+
requestProgress(requestIds: [$requestId]) { requestId progress data }
|
|
48
|
+
}
|
|
49
|
+
`,
|
|
50
|
+
variables: { requestId },
|
|
51
|
+
}, 20000, { requireCompletion: false, minEvents: 1 });
|
|
52
|
+
|
|
53
|
+
t.true(events.length > 0);
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import test from 'ava';
|
|
2
|
+
import serverFactory from '../../../../../../index.js';
|
|
3
|
+
import { createWsClient, ensureWsConnection, collectSubscriptionEvents } from '../../../../../helpers/subscriptions.js';
|
|
4
|
+
|
|
5
|
+
let testServer;
|
|
6
|
+
let wsClient;
|
|
7
|
+
|
|
8
|
+
test.before(async () => {
|
|
9
|
+
const { server, startServer } = await serverFactory();
|
|
10
|
+
startServer && await startServer();
|
|
11
|
+
testServer = server;
|
|
12
|
+
wsClient = createWsClient();
|
|
13
|
+
await ensureWsConnection(wsClient);
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
test.after.always('cleanup', async () => {
|
|
17
|
+
if (wsClient) wsClient.dispose();
|
|
18
|
+
if (testServer) await testServer.stop();
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
test('Gemini vendor streaming over subscriptions emits OAI-style deltas', async (t) => {
|
|
22
|
+
const response = await testServer.executeOperation({
|
|
23
|
+
query: `
|
|
24
|
+
query($text: String!, $chatHistory: [MultiMessage]!, $stream: Boolean, $aiStyle: String) {
|
|
25
|
+
sys_entity_agent(text: $text, chatHistory: $chatHistory, stream: $stream, aiStyle: $aiStyle) {
|
|
26
|
+
result
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
`,
|
|
30
|
+
variables: {
|
|
31
|
+
text: 'Say hi',
|
|
32
|
+
chatHistory: [{ role: 'user', content: ['Say hi'] }],
|
|
33
|
+
stream: true,
|
|
34
|
+
aiStyle: 'Google'
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
const requestId = response.body?.singleResult?.data?.sys_entity_agent?.result;
|
|
39
|
+
if (!requestId) {
|
|
40
|
+
t.pass('Skipping - Google vendor model not configured');
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const events = await collectSubscriptionEvents(wsClient, {
|
|
45
|
+
query: `
|
|
46
|
+
subscription($requestId: String!) {
|
|
47
|
+
requestProgress(requestIds: [$requestId]) { requestId progress data }
|
|
48
|
+
}
|
|
49
|
+
`,
|
|
50
|
+
variables: { requestId },
|
|
51
|
+
}, 20000, { requireCompletion: false, minEvents: 1 });
|
|
52
|
+
t.true(events.length > 0);
|
|
53
|
+
const hasDelta = events.some(e => {
|
|
54
|
+
const data = e?.data?.requestProgress?.data;
|
|
55
|
+
if (!data) return false;
|
|
56
|
+
try {
|
|
57
|
+
const parsed = JSON.parse(data);
|
|
58
|
+
return parsed?.choices?.[0]?.delta;
|
|
59
|
+
} catch (_) {
|
|
60
|
+
return false;
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
t.true(hasDelta);
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import test from 'ava';
|
|
2
|
+
import serverFactory from '../../../../../../index.js';
|
|
3
|
+
import { createWsClient, ensureWsConnection, collectSubscriptionEvents } from '../../../../../helpers/subscriptions.js';
|
|
4
|
+
|
|
5
|
+
let testServer;
|
|
6
|
+
let wsClient;
|
|
7
|
+
|
|
8
|
+
test.before(async () => {
|
|
9
|
+
const { server, startServer } = await serverFactory();
|
|
10
|
+
startServer && await startServer();
|
|
11
|
+
testServer = server;
|
|
12
|
+
wsClient = createWsClient();
|
|
13
|
+
await ensureWsConnection(wsClient);
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
test.after.always('cleanup', async () => {
|
|
17
|
+
if (wsClient) wsClient.dispose();
|
|
18
|
+
if (testServer) await testServer.stop();
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
test('XAI Grok vendor streaming over subscriptions emits OAI-style deltas', async (t) => {
|
|
22
|
+
const response = await testServer.executeOperation({
|
|
23
|
+
query: `
|
|
24
|
+
query($text: String!, $chatHistory: [MultiMessage]!, $stream: Boolean, $aiStyle: String) {
|
|
25
|
+
sys_entity_agent(text: $text, chatHistory: $chatHistory, stream: $stream, aiStyle: $aiStyle) {
|
|
26
|
+
result
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
`,
|
|
30
|
+
variables: {
|
|
31
|
+
text: 'Say hi',
|
|
32
|
+
chatHistory: [{ role: 'user', content: ['Say hi'] }],
|
|
33
|
+
stream: true,
|
|
34
|
+
aiStyle: 'XAI'
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
const requestId = response.body?.singleResult?.data?.sys_entity_agent?.result;
|
|
39
|
+
if (!requestId) {
|
|
40
|
+
t.pass('Skipping - XAI vendor model not configured');
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const events = await collectSubscriptionEvents(wsClient, {
|
|
45
|
+
query: `
|
|
46
|
+
subscription($requestId: String!) {
|
|
47
|
+
requestProgress(requestIds: [$requestId]) { requestId progress data }
|
|
48
|
+
}
|
|
49
|
+
`,
|
|
50
|
+
variables: { requestId },
|
|
51
|
+
}, 20000, { requireCompletion: false, minEvents: 1 });
|
|
52
|
+
|
|
53
|
+
t.true(events.length > 0);
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import test from 'ava';
|
|
2
|
+
import serverFactory from '../../../../../../index.js';
|
|
3
|
+
import { createWsClient, ensureWsConnection, collectSubscriptionEvents } from '../../../../../helpers/subscriptions.js';
|
|
4
|
+
|
|
5
|
+
let testServer;
|
|
6
|
+
let wsClient;
|
|
7
|
+
|
|
8
|
+
test.before(async () => {
|
|
9
|
+
const { server, startServer } = await serverFactory();
|
|
10
|
+
startServer && await startServer();
|
|
11
|
+
testServer = server;
|
|
12
|
+
wsClient = createWsClient();
|
|
13
|
+
await ensureWsConnection(wsClient);
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
test.after.always('cleanup', async () => {
|
|
17
|
+
if (wsClient) wsClient.dispose();
|
|
18
|
+
if (testServer) await testServer.stop();
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
test('OpenAI vendor streaming over subscriptions emits OAI-style deltas', async (t) => {
|
|
22
|
+
const response = await testServer.executeOperation({
|
|
23
|
+
query: `
|
|
24
|
+
query($text: String!, $chatHistory: [MultiMessage]!, $stream: Boolean, $aiStyle: String) {
|
|
25
|
+
sys_entity_agent(text: $text, chatHistory: $chatHistory, stream: $stream, aiStyle: $aiStyle) {
|
|
26
|
+
result
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
`,
|
|
30
|
+
variables: {
|
|
31
|
+
text: 'Say hi',
|
|
32
|
+
chatHistory: [{ role: 'user', content: ['Say hi'] }],
|
|
33
|
+
stream: true,
|
|
34
|
+
aiStyle: 'OpenAI'
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
const requestId = response.body?.singleResult?.data?.sys_entity_agent?.result;
|
|
39
|
+
if (!requestId) {
|
|
40
|
+
t.pass('Skipping - OpenAI vendor model not configured');
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const events = await collectSubscriptionEvents(wsClient, {
|
|
45
|
+
query: `
|
|
46
|
+
subscription($requestId: String!) {
|
|
47
|
+
requestProgress(requestIds: [$requestId]) { requestId progress data }
|
|
48
|
+
}
|
|
49
|
+
`,
|
|
50
|
+
variables: { requestId },
|
|
51
|
+
}, 20000, { requireCompletion: false, minEvents: 1 });
|
|
52
|
+
|
|
53
|
+
t.true(events.length > 0);
|
|
54
|
+
|
|
55
|
+
// Ensure streamed chunks (when they include model) use gpt-4.1 (not mini)
|
|
56
|
+
const models = events
|
|
57
|
+
.map(e => {
|
|
58
|
+
try {
|
|
59
|
+
return JSON.parse(e?.data?.requestProgress?.data || '{}')?.model;
|
|
60
|
+
} catch (_) {
|
|
61
|
+
return undefined;
|
|
62
|
+
}
|
|
63
|
+
})
|
|
64
|
+
.filter(Boolean);
|
|
65
|
+
|
|
66
|
+
if (models.length > 0) {
|
|
67
|
+
t.truthy(models.find(m => /gpt-4\.1(?!-mini)/.test(m)));
|
|
68
|
+
t.falsy(models.find(m => /gpt-4\.1-mini/.test(m)));
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import test from 'ava';
|
|
2
|
+
import sinon from 'sinon';
|
|
3
|
+
|
|
4
|
+
const mockGoogleResponse = {
|
|
5
|
+
searchInformation: {
|
|
6
|
+
totalResults: '123',
|
|
7
|
+
searchTime: 0.12
|
|
8
|
+
},
|
|
9
|
+
items: [
|
|
10
|
+
{
|
|
11
|
+
title: 'Pikachu - Wikipedia',
|
|
12
|
+
link: 'https://en.wikipedia.org/wiki/Pikachu',
|
|
13
|
+
snippet: 'Pikachu is a species of Pokémon...'
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
title: 'Pokemon News - Official Site',
|
|
17
|
+
link: 'https://www.pokemon.com/us',
|
|
18
|
+
snippet: 'The official source for Pokémon news...'
|
|
19
|
+
}
|
|
20
|
+
]
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
// Build a minimal stub pathway for google_cse returning canned results
|
|
24
|
+
const buildStubGooglePathway = () => ({
|
|
25
|
+
name: 'google_cse',
|
|
26
|
+
// Simulate the core rootResolver returning data.result
|
|
27
|
+
rootResolver: async () => {
|
|
28
|
+
return { result: JSON.stringify(mockGoogleResponse) };
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
// Build a minimal resolver object to pass to executePathway
|
|
33
|
+
const buildResolver = () => ({
|
|
34
|
+
errors: [],
|
|
35
|
+
tool: null,
|
|
36
|
+
mergeResults: () => {},
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
// Ensure required env vars exist before importing config/tool
|
|
40
|
+
const setEnv = (t) => {
|
|
41
|
+
t.context.originalEnv = { ...process.env };
|
|
42
|
+
process.env.OPENAI_API_KEY = 'test-openai-key';
|
|
43
|
+
process.env.GOOGLE_CSE_KEY = 'test-google-key';
|
|
44
|
+
process.env.GOOGLE_CSE_CX = 'test-google-cx';
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
const restoreEnv = (t) => {
|
|
48
|
+
process.env = t.context.originalEnv;
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
// We import modules lazily after env vars are set to avoid config init errors
|
|
52
|
+
const loadModules = async () => {
|
|
53
|
+
const { config } = await import('../../../../../config.js');
|
|
54
|
+
const toolModule = await import('../../../../../pathways/system/entity/tools/sys_tool_google_search.js');
|
|
55
|
+
return { config, tool: toolModule.default };
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
// Helper to inject stub google_cse pathway
|
|
59
|
+
const injectStubPathway = (config) => {
|
|
60
|
+
const existing = config.get('pathways') || {};
|
|
61
|
+
const modified = { ...existing, google_cse: buildStubGooglePathway() };
|
|
62
|
+
config.load({ pathways: modified });
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
// Test: normalization to SearchResponse
|
|
66
|
+
|
|
67
|
+
test('sys_tool_google_search normalizes Google items into SearchResponse', async (t) => {
|
|
68
|
+
setEnv(t);
|
|
69
|
+
const { config, tool } = await loadModules();
|
|
70
|
+
injectStubPathway(config);
|
|
71
|
+
|
|
72
|
+
const resolver = buildResolver();
|
|
73
|
+
const args = { q: 'pokemon', userMessage: 'testing' };
|
|
74
|
+
|
|
75
|
+
const resultStr = await tool.executePathway({ args, runAllPrompts: null, resolver });
|
|
76
|
+
t.truthy(resultStr, 'Should return a stringified JSON response');
|
|
77
|
+
|
|
78
|
+
const result = JSON.parse(resultStr);
|
|
79
|
+
t.is(result._type, 'SearchResponse');
|
|
80
|
+
t.true(Array.isArray(result.value));
|
|
81
|
+
|
|
82
|
+
// Normalized items should match the CSE items length
|
|
83
|
+
const items = result.value;
|
|
84
|
+
t.is(items.length, mockGoogleResponse.items.length);
|
|
85
|
+
t.truthy(items[0].searchResultId);
|
|
86
|
+
t.is(items[0].title, mockGoogleResponse.items[0].title);
|
|
87
|
+
t.is(items[0].url, mockGoogleResponse.items[0].link);
|
|
88
|
+
t.is(items[0].content, mockGoogleResponse.items[0].snippet);
|
|
89
|
+
|
|
90
|
+
// Tool metadata is set
|
|
91
|
+
t.truthy(resolver.tool);
|
|
92
|
+
const toolMeta = JSON.parse(resolver.tool);
|
|
93
|
+
t.is(toolMeta.toolUsed, 'GoogleSearch');
|
|
94
|
+
|
|
95
|
+
restoreEnv(t);
|
|
96
|
+
});
|