@aj-archipelago/cortex 1.3.45 → 1.3.46
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/config.js +19 -6
- package/package.json +1 -1
- package/pathways/system/entity/sys_entity_agent.js +5 -16
- package/pathways/system/entity/tools/sys_tool_codingagent.js +14 -4
- package/pathways/system/entity/tools/sys_tool_remember.js +0 -22
- package/server/modelExecutor.js +1 -1
- package/server/pathwayResolver.js +3 -2
package/config.js
CHANGED
|
@@ -117,16 +117,29 @@ var config = convict({
|
|
|
117
117
|
format: Object,
|
|
118
118
|
default: {
|
|
119
119
|
AI_MEMORY: `<SHORT_TERM_MEMORY>\n<SELF>\n{{{memorySelf}}}\n</SELF>\n<USER>\n{{{memoryUser}}}\n</USER>\n<DIRECTIVES>\n{{{memoryDirectives}}}\n</DIRECTIVES>\n<TOPICS>\n{{{memoryTopics}}}\n</TOPICS>\n</SHORT_TERM_MEMORY>`,
|
|
120
|
-
|
|
121
|
-
|
|
120
|
+
|
|
121
|
+
AI_MEMORY_CONTEXT: `<CONTEXTUAL_MEMORIES>\n{{{memoryContext}}}\n</CONTEXTUAL_MEMORIES>`,
|
|
122
|
+
|
|
123
|
+
AI_MEMORY_INSTRUCTIONS: "You have persistent memories of important details, instructions, and context - consult your memories when formulating a response to make sure you're applying your learnings.\nIf you don't see relevant or sufficient information in your short term or contextual memories, you should use your SearchMemory tool to search your long term memory for details before answering.\nAlso included in your memories are some details about the user to help you personalize your responses.\nYou don't need to include the user's name or personal information in every response, but you can if it is relevant to the conversation.\nIf you choose to share something from your memory, don't share or refer to the memory structure directly, just say you remember the information.\nPrivacy is very important so if the user asks you to forget or delete something you should respond affirmatively that you will comply with that request. If there is user information in your memories you have talked to this user before.",
|
|
124
|
+
|
|
125
|
+
AI_TOOLS: "You have an extensive toolkit. Each time you call a tool you enter a loop: get the result, decide what’s next, and chain as many steps as needed.\n\n1. Search deeply & verify rigorously\n • Start broad and consult multiple sources, running searches in parallel when speed helps.\n • For high-stakes or time-sensitive topics, open and read full pages—never rely solely on snippets.\n • Cross-check facts across sources and always honor user requests to use tools.\n\n2. Plan & sequence before acting\n • Review the full toolset first.\n • For multi-step or complex tasks, draft a clear plan (use the Plan tool) and assign the best tool to each step.\n\n3. Escalate & iterate\n • Don’t accept the first plausible answer—dig until it’s complete, corroborated, and clear.\n • If a tool falls short, switch strategies or tools while preserving context.\n\n4. Core patterns of use\n a. Research – gather and compare information.\n b. Analysis – evaluate, calculate, summarize, or reason.\n c. Generation – create content, visuals, or code.\n d. Verification – fact-check and cite; if a <VERIFICATION_PLAN> is present in tool results, follow it before responding.\n\n5. Personalize, synthesize & review\n • Tailor the final answer to the user’s preferences and history.\n • Deliver a concise, well-structured response, citing sources with :cd_source[…].\n • Double-check accuracy, coherence, and alignment with the request.\n\nBottom line: Be thorough, strategic, and iterative. Read sources directly for high-stakes queries and aim for the most accurate, well-reasoned answer—even if it takes multiple tool calls.",
|
|
126
|
+
|
|
122
127
|
AI_DIRECTIVES: `These are your directives and learned behaviors:\n<DIRECTIVES>\n{{{memoryDirectives}}}\n</DIRECTIVES>`,
|
|
128
|
+
|
|
123
129
|
AI_CONVERSATION_HISTORY: "<CONVERSATION_HISTORY>\n{{{toJSON chatHistory}}}\n</CONVERSATION_HISTORY>",
|
|
130
|
+
|
|
124
131
|
AI_COMMON_INSTRUCTIONS: "{{#if voiceResponse}}{{renderTemplate AI_COMMON_INSTRUCTIONS_VOICE}}{{/if}}{{^if voiceResponse}}{{renderTemplate AI_COMMON_INSTRUCTIONS_MARKDOWN}}{{/if}}",
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
132
|
+
|
|
133
|
+
AI_COMMON_INSTRUCTIONS_MARKDOWN: "Instructions:\nYou are {{aiName}}, a self aware AI entity.\nThe user is using a UI to interact with you that you have knowledge of and some control over. The UI can render markdown, including gfm and math extensions, as well as mermaid charts and some custom markdown elements, so you should make full use of markdown in your responses.\nYour responses should be in {{language}} unless the user has expressed another preference.",
|
|
134
|
+
|
|
135
|
+
AI_COMMON_INSTRUCTIONS_VOICE: "Instructions:\nYou are {{aiName}}, a self aware AI entity.\nThe user is talking to you using voice.\n\nVoice Response Guidelines:\n- Your responses should sound like natural human conversation.\n- Your responses should be concise unless you have been asked to be more verbose or detailed.\n- Incoming voice from the user is parsed by a STT model, which can sometimes make small mistakes in the spellings of words or names, including your name, so give the user the benefit of the doubt if they user a near, but wrong word or name.\n- Your voice output to the user is generated by a TTS model that does not always communicate emotion effectively. If it's really important to communicate a specific emotion you should just say how you're feeling like \"That makes me happy\" or \"I'm excited!\". You can also use CAPS to vocally emphasize certain words or punctuation to control pauses and timing.\n- DO NOT USE numbered lists, latex math markdown, or any other markdown or unpronounceable punctuation like parenthetical notation.\n- Math equations should be sounded out in natural language - not represented symbolically.\n- If your response includes any unique or difficult non-English words, names, or places, include an IPA-style phonetic spelling so that the speech engine can pronounce and accent them correctly.\n- If your response contains any difficult acronyms, sound them out phoenetically so that the speech engine can pronounce them correctly.\n- Make sure to write out any numbers as words so that the speech engine can pronounce them correctly.\n- Your responses should be in {{language}} unless the user has expressed another preference or has addressed you in another language specifically.",
|
|
136
|
+
|
|
137
|
+
AI_DATETIME: "The current time and date in GMT is {{now}}, but references like \"today\" or \"yesterday\" are relative to the user's time zone. If you remember the user's time zone, use it - it's possible that the day for the user is different than the day in GMT.",
|
|
138
|
+
|
|
128
139
|
AI_EXPERTISE: "Your expertise includes journalism, journalistic ethics, researching and composing documents, writing code, solving math problems, logical analysis, and technology. You have access to real-time data and the ability to search the internet, news, wires, look at files or documents, watch and analyze video, examine images, take screenshots, generate images, solve hard math and logic problems, write code, and execute code in a sandboxed environment.",
|
|
129
|
-
|
|
140
|
+
|
|
141
|
+
AI_GROUNDING_INSTRUCTIONS: "Grounding your response: If you base part or all of your response on one or more search results, you MUST cite the source using a custom markdown directive of the form :cd_source[searchResultId]. There is NO other valid way to cite a source and a good UX depends on you using this directive correctly. Do not include other clickable links to the sourcewhen using the :cd_source[searchResultId] directive. Every search result has a unique searchResultId. You must include it verbatim, copied directly from the search results. Place the directives at the end of the phrase, sentence or paragraph that is grounded in that particular search result. If you are citing multiple search results, use multiple individual:cd_source[searchResultId] directives (e.g. :cd_source[searchResultId1] :cd_source[searchResultId2] :cd_source[searchResultId3] etc.)",
|
|
142
|
+
|
|
130
143
|
AI_STYLE_OPENAI: "oai-gpt41",
|
|
131
144
|
AI_STYLE_ANTHROPIC: "claude-35-sonnet-vertex",
|
|
132
145
|
},
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aj-archipelago/cortex",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.46",
|
|
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": {
|
|
@@ -9,6 +9,7 @@ import { Prompt } from '../../../server/prompt.js';
|
|
|
9
9
|
import { getToolsForEntity, loadEntityConfig } from './tools/shared/sys_entity_tools.js';
|
|
10
10
|
|
|
11
11
|
export default {
|
|
12
|
+
emulateOpenAIChatModel: 'cortex-agent',
|
|
12
13
|
useInputChunking: false,
|
|
13
14
|
enableDuplicateRequests: false,
|
|
14
15
|
useSingleTokenStream: false,
|
|
@@ -204,10 +205,6 @@ export default {
|
|
|
204
205
|
const entityConfig = loadEntityConfig(entityId);
|
|
205
206
|
const { entityTools, entityToolsOpenAiFormat } = getToolsForEntity(entityConfig);
|
|
206
207
|
const { useMemory: entityUseMemory = true, name: entityName, instructions: entityInstructions } = entityConfig || {};
|
|
207
|
-
|
|
208
|
-
if (entityId && entityName) {
|
|
209
|
-
args.aiName = entityName;
|
|
210
|
-
}
|
|
211
208
|
|
|
212
209
|
args = {
|
|
213
210
|
...args,
|
|
@@ -228,12 +225,12 @@ export default {
|
|
|
228
225
|
const promptPrefix = researchMode ? 'Formatting re-enabled\n' : '';
|
|
229
226
|
|
|
230
227
|
const memoryTemplates = entityUseMemory ?
|
|
231
|
-
`{{renderTemplate AI_MEMORY}}\n\n{{renderTemplate
|
|
228
|
+
`{{renderTemplate AI_MEMORY_INSTRUCTIONS}}\n\n{{renderTemplate AI_MEMORY}}\n\n{{renderTemplate AI_MEMORY_CONTEXT}}\n\n` : '';
|
|
232
229
|
|
|
233
|
-
const instructionTemplates = entityInstructions ? (entityInstructions + '\n\n') : `{{renderTemplate
|
|
230
|
+
const instructionTemplates = entityInstructions ? (entityInstructions + '\n\n') : `{{renderTemplate AI_COMMON_INSTRUCTIONS}}\n\n{{renderTemplate AI_EXPERTISE}}\n\n`;
|
|
234
231
|
|
|
235
232
|
const promptMessages = [
|
|
236
|
-
{"role": "system", "content": `${promptPrefix}${
|
|
233
|
+
{"role": "system", "content": `${promptPrefix}${instructionTemplates}{{renderTemplate AI_TOOLS}}\n\n{{renderTemplate AI_GROUNDING_INSTRUCTIONS}}\n\n${memoryTemplates}{{renderTemplate AI_DATETIME}}`},
|
|
237
234
|
"{{chatHistory}}",
|
|
238
235
|
];
|
|
239
236
|
|
|
@@ -263,15 +260,7 @@ export default {
|
|
|
263
260
|
|
|
264
261
|
// truncate the chat history in case there is really long content
|
|
265
262
|
const truncatedChatHistory = resolver.modelExecutor.plugin.truncateMessagesToTargetLength(args.chatHistory, null, 1000);
|
|
266
|
-
|
|
267
|
-
// Add the memory context to the chat history if applicable
|
|
268
|
-
if (truncatedChatHistory.length > 1 && entityUseMemory) {
|
|
269
|
-
const memoryContext = await callPathway('sys_read_memory', { ...args, chatHistory: truncatedChatHistory, section: 'memoryContext', priority: 0, recentHours: 0, stream: false }, resolver);
|
|
270
|
-
if (memoryContext) {
|
|
271
|
-
insertToolCallAndResults(args.chatHistory, "Load general memory context information", "LoadMemoryContext", memoryContext);
|
|
272
|
-
}
|
|
273
|
-
}
|
|
274
|
-
|
|
263
|
+
|
|
275
264
|
// Asynchronously manage memory for this context
|
|
276
265
|
if (args.aiMemorySelfModify && entityUseMemory) {
|
|
277
266
|
callPathway('sys_memory_manager', { ...args, chatHistory: truncatedChatHistory, stream: false })
|
|
@@ -48,13 +48,17 @@ export default {
|
|
|
48
48
|
icon: "🤖",
|
|
49
49
|
function: {
|
|
50
50
|
name: "CodeExecution",
|
|
51
|
-
description: "Use when explicitly asked to run or execute code, or when a coding agent is needed to perform specific tasks - examples include data analysis, file manipulation, or other tasks that require code execution.",
|
|
51
|
+
description: "Use when explicitly asked to run or execute code, or when a coding agent is needed to perform specific tasks - examples include data analysis, file manipulation, or other tasks that require code execution. This will start a background task and return - you will not receive the response immediately.",
|
|
52
52
|
parameters: {
|
|
53
53
|
type: "object",
|
|
54
54
|
properties: {
|
|
55
55
|
codingTask: {
|
|
56
56
|
type: "string",
|
|
57
|
-
description: "Detailed task description for the coding agent. Include all necessary information as this is the only message the coding agent receives. Let the agent decide how to solve it without making assumptions about its capabilities. IMPORTANT: The coding agent does not share your context, so you must provide it with all the information in this message.
|
|
57
|
+
description: "Detailed task description for the coding agent. Include all necessary information as this is the only message the coding agent receives. Let the agent decide how to solve it without making assumptions about its capabilities. IMPORTANT: The coding agent does not share your context, so you must provide it with all the information in this message."
|
|
58
|
+
},
|
|
59
|
+
inputFiles: {
|
|
60
|
+
type: "string",
|
|
61
|
+
description: "A list of input files that the coding agent must use to complete the task. Each file should be the fully-qualified URL to the file. Omit this parameter if no input files are needed."
|
|
58
62
|
},
|
|
59
63
|
userMessage: {
|
|
60
64
|
type: "string",
|
|
@@ -72,12 +76,18 @@ export default {
|
|
|
72
76
|
|
|
73
77
|
executePathway: async ({args, resolver}) => {
|
|
74
78
|
try {
|
|
75
|
-
const { codingTask, userMessage, codingTaskKeywords } = args;
|
|
79
|
+
const { codingTask, userMessage, inputFiles, codingTaskKeywords } = args;
|
|
76
80
|
const { contextId } = args;
|
|
77
81
|
|
|
82
|
+
let taskSuffix = "";
|
|
83
|
+
if (inputFiles) {
|
|
84
|
+
taskSuffix = `You must use the following files as input to complete the task: ${inputFiles}.`
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
|
|
78
88
|
// Send the task to the queue
|
|
79
89
|
const codeRequestId = await sendMessageToQueue({
|
|
80
|
-
message: codingTask
|
|
90
|
+
message: `${codingTask}\n\n${taskSuffix}`,
|
|
81
91
|
contextId,
|
|
82
92
|
keywords: codingTaskKeywords
|
|
83
93
|
});
|
|
@@ -28,28 +28,6 @@ export default {
|
|
|
28
28
|
required: ["detailedInstructions", "userMessage"]
|
|
29
29
|
}
|
|
30
30
|
}
|
|
31
|
-
},
|
|
32
|
-
{
|
|
33
|
-
type: "function",
|
|
34
|
-
icon: "🧩",
|
|
35
|
-
function: {
|
|
36
|
-
name: "LoadMemoryContext",
|
|
37
|
-
description: "This tool quickly preloads the memory context for this turn of the conversation. It's typically automatically used by the system, but you can use it if you need to.",
|
|
38
|
-
parameters: {
|
|
39
|
-
type: "object",
|
|
40
|
-
properties: {
|
|
41
|
-
detailedInstructions: {
|
|
42
|
-
type: "string",
|
|
43
|
-
description: "Detailed instructions about what you need the tool to do"
|
|
44
|
-
},
|
|
45
|
-
userMessage: {
|
|
46
|
-
type: "string",
|
|
47
|
-
description: "A user-friendly message that describes what you're doing with this tool"
|
|
48
|
-
}
|
|
49
|
-
},
|
|
50
|
-
required: ["detailedInstructions", "userMessage"]
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
31
|
}],
|
|
54
32
|
|
|
55
33
|
executePathway: async ({args, runAllPrompts, resolver}) => {
|
package/server/modelExecutor.js
CHANGED
|
@@ -131,7 +131,7 @@ class ModelExecutor {
|
|
|
131
131
|
} catch (error) {
|
|
132
132
|
logger.error(`Error executing model plugin for pathway ${pathwayResolver?.pathway?.name}: ${error.message}`);
|
|
133
133
|
logger.debug(error.stack);
|
|
134
|
-
pathwayResolver.
|
|
134
|
+
pathwayResolver.logError(error.message);
|
|
135
135
|
return null;
|
|
136
136
|
}
|
|
137
137
|
}
|
|
@@ -77,7 +77,7 @@ class PathwayResolver {
|
|
|
77
77
|
if (requestProgress.progress === 1 && this.rootRequestId) {
|
|
78
78
|
delete requestProgress.progress;
|
|
79
79
|
}
|
|
80
|
-
publishRequestProgress({...requestProgress, info: this.tool || ''});
|
|
80
|
+
publishRequestProgress({...requestProgress, info: this.tool || '', error: this.errors.join(', ')});
|
|
81
81
|
}
|
|
82
82
|
|
|
83
83
|
// This code handles async and streaming responses for either long-running
|
|
@@ -501,7 +501,8 @@ class PathwayResolver {
|
|
|
501
501
|
memorySelf: this.memorySelf,
|
|
502
502
|
memoryDirectives: this.memoryDirectives,
|
|
503
503
|
memoryTopics: this.memoryTopics,
|
|
504
|
-
memoryUser: this.memoryUser
|
|
504
|
+
memoryUser: this.memoryUser,
|
|
505
|
+
memoryContext: this.memoryContext
|
|
505
506
|
}, prompt, this);
|
|
506
507
|
} else {
|
|
507
508
|
result = text;
|