@aj-archipelago/cortex 1.3.31 → 1.3.32
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/helper-apps/cortex-file-handler/package.json +1 -1
- package/package.json +2 -2
- package/pathways/image_flux.js +1 -1
- package/pathways/system/entity/memory/shared/sys_memory_helpers.js +9 -1
- package/pathways/system/entity/sys_entity_start.js +4 -7
- package/pathways/system/entity/sys_generator_image.js +2 -3
- package/pathways/system/entity/sys_generator_memory.js +2 -3
- package/pathways/system/entity/sys_generator_quick.js +1 -1
- package/pathways/system/entity/sys_router_tool.js +10 -2
- package/pathways/transcribe_gemini.js +12 -8
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aj-archipelago/cortex",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.32",
|
|
4
4
|
"description": "Cortex is a GraphQL API for AI. It provides a simple, extensible interface for using AI services from OpenAI, Azure and others.",
|
|
5
5
|
"private": false,
|
|
6
6
|
"repository": {
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
"type": "module",
|
|
34
34
|
"homepage": "https://github.com/aj-archipelago/cortex#readme",
|
|
35
35
|
"dependencies": {
|
|
36
|
-
"@aj-archipelago/subvibe": "^1.0.
|
|
36
|
+
"@aj-archipelago/subvibe": "^1.0.10",
|
|
37
37
|
"@apollo/server": "^4.7.3",
|
|
38
38
|
"@apollo/server-plugin-response-cache": "^4.1.2",
|
|
39
39
|
"@apollo/utils.keyvadapter": "^3.0.0",
|
package/pathways/image_flux.js
CHANGED
|
@@ -139,6 +139,14 @@ const addToolResults = (chatHistory, result, toolCallId) => {
|
|
|
139
139
|
return { chatHistory, toolCallId };
|
|
140
140
|
};
|
|
141
141
|
|
|
142
|
+
const insertToolCallAndResults = (chatHistory, toolArgs, toolName, result = null, toolCallId = getUniqueId()) => {
|
|
143
|
+
const lastMessage = chatHistory.length > 0 ? chatHistory.pop() : null;
|
|
144
|
+
addToolCalls(chatHistory, toolArgs, toolName, toolCallId);
|
|
145
|
+
addToolResults(chatHistory, result, toolCallId);
|
|
146
|
+
chatHistory.push(lastMessage);
|
|
147
|
+
return { chatHistory, toolCallId };
|
|
148
|
+
};
|
|
149
|
+
|
|
142
150
|
const modifyText = (text, modifications) => {
|
|
143
151
|
let modifiedText = text || '';
|
|
144
152
|
|
|
@@ -225,4 +233,4 @@ const modifyText = (text, modifications) => {
|
|
|
225
233
|
return modifiedText;
|
|
226
234
|
};
|
|
227
235
|
|
|
228
|
-
export { normalizeMemoryFormat, enforceTokenLimit, addToolCalls, addToolResults, modifyText };
|
|
236
|
+
export { normalizeMemoryFormat, enforceTokenLimit, addToolCalls, addToolResults, modifyText, insertToolCallAndResults };
|
|
@@ -5,7 +5,7 @@ import logger from '../../../lib/logger.js';
|
|
|
5
5
|
import { chatArgsHasImageUrl } from '../../../lib/util.js';
|
|
6
6
|
import { QueueServiceClient } from '@azure/storage-queue';
|
|
7
7
|
import { config } from '../../../config.js';
|
|
8
|
-
import {
|
|
8
|
+
import { insertToolCallAndResults } from './memory/shared/sys_memory_helpers.js';
|
|
9
9
|
|
|
10
10
|
const connectionString = process.env.AZURE_STORAGE_CONNECTION_STRING;
|
|
11
11
|
let queueClient;
|
|
@@ -94,13 +94,10 @@ export default {
|
|
|
94
94
|
if (args.chatHistory.length > 1) {
|
|
95
95
|
const memoryContext = await callPathway('sys_read_memory', { ...args, section: 'memoryContext', priority: 0, recentHours: 0, stream: false }, pathwayResolver);
|
|
96
96
|
if (memoryContext) {
|
|
97
|
-
|
|
98
|
-
const { toolCallId } = addToolCalls(args.chatHistory, "search memory for relevant information", "memory_lookup");
|
|
99
|
-
addToolResults(args.chatHistory, memoryContext, toolCallId);
|
|
100
|
-
args.chatHistory.push(lastMessage);
|
|
97
|
+
insertToolCallAndResults(args.chatHistory, "search memory for relevant information", "memory_lookup", memoryContext);
|
|
101
98
|
}
|
|
102
99
|
}
|
|
103
|
-
|
|
100
|
+
|
|
104
101
|
// If we're using voice, get a quick response to say
|
|
105
102
|
let ackResponse = null;
|
|
106
103
|
if (args.voiceResponse) {
|
|
@@ -222,7 +219,7 @@ export default {
|
|
|
222
219
|
title = await fetchTitleResponsePromise;
|
|
223
220
|
|
|
224
221
|
pathwayResolver.tool = JSON.stringify({
|
|
225
|
-
hideFromModel: toolCallbackName ? true : false,
|
|
222
|
+
hideFromModel: (!args.stream && toolCallbackName) ? true : false,
|
|
226
223
|
toolCallbackName,
|
|
227
224
|
title,
|
|
228
225
|
search: toolCallbackName === 'sys_generator_results' ? true : false,
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
import { callPathway } from '../../../lib/pathwayTools.js';
|
|
4
4
|
import { Prompt } from '../../../server/prompt.js';
|
|
5
5
|
import logger from '../../../lib/logger.js';
|
|
6
|
-
import {
|
|
6
|
+
import { insertToolCallAndResults } from './memory/shared/sys_memory_helpers.js';
|
|
7
7
|
|
|
8
8
|
export default {
|
|
9
9
|
prompt: [],
|
|
@@ -73,8 +73,7 @@ Instructions: As part of a conversation with the user, you have been asked to cr
|
|
|
73
73
|
|
|
74
74
|
// add the tool_calls and tool_results to the chatHistory
|
|
75
75
|
imageResults.forEach((imageResult, index) => {
|
|
76
|
-
|
|
77
|
-
addToolResults(chatHistory, imageResult, toolCallId, "generate_image");
|
|
76
|
+
insertToolCallAndResults(chatHistory, imagePrompts[index], "generate_image", imageResult);
|
|
78
77
|
});
|
|
79
78
|
|
|
80
79
|
const result = await runAllPrompts({ ...args });
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { callPathway } from '../../../lib/pathwayTools.js';
|
|
2
|
-
import {
|
|
2
|
+
import { insertToolCallAndResults } from './memory/shared/sys_memory_helpers.js';
|
|
3
3
|
|
|
4
4
|
export default {
|
|
5
5
|
prompt:
|
|
@@ -20,8 +20,7 @@ export default {
|
|
|
20
20
|
|
|
21
21
|
const memoryContext = await callPathway('sys_search_memory', { ...args, stream: false, section: 'memoryAll', updateContext: true });
|
|
22
22
|
if (memoryContext) {
|
|
23
|
-
|
|
24
|
-
addToolResults(args.chatHistory, memoryContext, toolCallId);
|
|
23
|
+
insertToolCallAndResults(args.chatHistory, "search memory for relevant information", "memory_lookup", memoryContext);
|
|
25
24
|
}
|
|
26
25
|
|
|
27
26
|
let result;
|
|
@@ -15,7 +15,7 @@ export default {
|
|
|
15
15
|
let pathwayResolver = resolver;
|
|
16
16
|
|
|
17
17
|
const promptMessages = [
|
|
18
|
-
{"role": "system", "content": `{{renderTemplate AI_MEMORY}}\n\n{{renderTemplate AI_COMMON_INSTRUCTIONS}}\n{{renderTemplate AI_EXPERTISE}}
|
|
18
|
+
{"role": "system", "content": `{{renderTemplate AI_MEMORY}}\n\n{{renderTemplate AI_COMMON_INSTRUCTIONS}}\n{{renderTemplate AI_EXPERTISE}}\n{{renderTemplate AI_MEMORY_INSTRUCTIONS}}\n{{renderTemplate AI_DATETIME}}`},
|
|
19
19
|
"{{chatHistory}}",
|
|
20
20
|
];
|
|
21
21
|
|
|
@@ -56,8 +56,16 @@ If you decide to use a tool, return a JSON object in this format:
|
|
|
56
56
|
|
|
57
57
|
toolMessage Guidelines:
|
|
58
58
|
- The message should be consistent in style and tone with the rest of your responses in the conversation history.
|
|
59
|
-
- The message should be brief
|
|
60
|
-
-
|
|
59
|
+
- The message should be brief, conversational, and flow naturally with the conversation history.
|
|
60
|
+
- Use contractions (I'm, don't, let's) and informal language to sound more natural.
|
|
61
|
+
- Include slight verbal hesitations or false starts occasionally (e.g., "So... I think what we could do here is" or "Actually, let me try a different approach").
|
|
62
|
+
- Vary sentence length and structure - mix short punchy sentences with longer ones.
|
|
63
|
+
- Include casual transitions and filler phrases that humans use: "you know," "basically," "so," "actually," "by the way," "anyway," etc.
|
|
64
|
+
- Express uncertainty when appropriate with phrases like "I'm pretty sure," "If I remember correctly," or "I think."
|
|
65
|
+
- Reference personal preferences or opinions occasionally ("I personally find that..." or "I tend to prefer...").
|
|
66
|
+
- Occasionally make minor self-corrections as humans do ("Wait, let me rephrase that" or "Actually, I meant to say...").
|
|
67
|
+
- Humans don't refer to tools - stall for time by saying things like "Let me think about this for a sec," "Drawing that up for you now," or "Working on it..." Humans also stall with vocalizations like "hmm," "let's see," or "give me a moment."
|
|
68
|
+
- When appropriate, react emotionally to content with expressions like "Wow!" or "That's interesting!"
|
|
61
69
|
|
|
62
70
|
If no tool is required, return:
|
|
63
71
|
{"toolRequired": false, "toolReason": "explanation of why no tool was necessary"}
|
|
@@ -5,7 +5,6 @@ import { Prompt } from "../server/prompt.js";
|
|
|
5
5
|
|
|
6
6
|
const OFFSET_CHUNK = 500; //seconds of each chunk offset, only used if helper does not provide
|
|
7
7
|
|
|
8
|
-
// Function to properly detect YouTube URLs
|
|
9
8
|
function isYoutubeUrl(url) {
|
|
10
9
|
try {
|
|
11
10
|
const urlObj = new URL(url);
|
|
@@ -23,6 +22,10 @@ function isYoutubeUrl(url) {
|
|
|
23
22
|
if (urlObj.pathname.startsWith("/embed/")) {
|
|
24
23
|
return urlObj.pathname.length > 7; // '/embed/' is 7 chars
|
|
25
24
|
}
|
|
25
|
+
// For shorts URLs, verify they have a video ID in the path
|
|
26
|
+
if (urlObj.pathname.startsWith("/shorts/")) {
|
|
27
|
+
return urlObj.pathname.length > 8; // '/shorts/' is 8 chars
|
|
28
|
+
}
|
|
26
29
|
return false;
|
|
27
30
|
}
|
|
28
31
|
|
|
@@ -45,7 +48,7 @@ export default {
|
|
|
45
48
|
"{{messages}}",
|
|
46
49
|
]}),
|
|
47
50
|
],
|
|
48
|
-
model: 'gemini-
|
|
51
|
+
model: 'gemini-pro-20-vision',
|
|
49
52
|
inputParameters: {
|
|
50
53
|
file: ``,
|
|
51
54
|
language: ``,
|
|
@@ -96,7 +99,10 @@ export default {
|
|
|
96
99
|
sendProgress(true);
|
|
97
100
|
intervalId = setInterval(() => sendProgress(true), 3000);
|
|
98
101
|
|
|
99
|
-
const { file,
|
|
102
|
+
const { file, wordTimestamped, maxLineWidth } = args;
|
|
103
|
+
|
|
104
|
+
const responseFormat = args.responseFormat || 'text';
|
|
105
|
+
|
|
100
106
|
if(!file) {
|
|
101
107
|
throw new Error("Please provide a file to transcribe.");
|
|
102
108
|
}
|
|
@@ -129,9 +135,7 @@ export default {
|
|
|
129
135
|
respectLimitsPrompt += ` These subtitles will be shown in a ${possiblePlacement} formatted video player. Each subtitle line should not exceed ${maxLineWidth} characters to fit the player.`;
|
|
130
136
|
}
|
|
131
137
|
|
|
132
|
-
function getMessages(file
|
|
133
|
-
|
|
134
|
-
const responseFormat = format !== 'text' ? 'VTT' : 'text';
|
|
138
|
+
function getMessages(file) {
|
|
135
139
|
|
|
136
140
|
// Base system content that's always included
|
|
137
141
|
let systemContent = `Instructions:
|
|
@@ -216,7 +220,7 @@ REMEMBER:
|
|
|
216
220
|
const messages = [
|
|
217
221
|
{"role": "system", "content": systemContent},
|
|
218
222
|
{"role": "user", "content": [
|
|
219
|
-
`{ type: 'text', text: 'Transcribe this file in ${responseFormat} format.${respectLimitsPrompt}' }`,
|
|
223
|
+
`{ type: 'text', text: 'Transcribe this file in ${responseFormat} format.${respectLimitsPrompt} Output only the transcription, no other text or comments or formatting.' }`,
|
|
220
224
|
JSON.stringify({
|
|
221
225
|
type: 'image_url',
|
|
222
226
|
url: file,
|
|
@@ -266,7 +270,7 @@ REMEMBER:
|
|
|
266
270
|
|
|
267
271
|
const result = await processChunksParallel(chunks, args);
|
|
268
272
|
|
|
269
|
-
if (['srt','vtt'].includes(responseFormat) || wordTimestamped) { // align subtitles for formats
|
|
273
|
+
if (['srt','vtt'].includes(responseFormat.toLowerCase()) || wordTimestamped) { // align subtitles for formats
|
|
270
274
|
const offsets = chunks.map((chunk, index) => chunk?.offset || index * OFFSET_CHUNK);
|
|
271
275
|
return alignSubtitles(result, responseFormat, offsets);
|
|
272
276
|
}
|