@aj-archipelago/cortex 1.3.44 → 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 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
- 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 information in your short term memory, you should use your SearchMemory tool to search your long term memory for details.\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.",
121
- AI_TOOLS: "You can execute tools in a loop agentically - you will have a chance to evaluate every tool response before deciding what action to take next - there is no time or execution limit. You have access to a powerful set of tools to help accomplish tasks and deliver the best responses. Instructions for tool use:\n\n1. Always dig deep, verify and cross-check:\n- Take your time and use tools as many times as needed to ensure truth, accuracy, depth, and completeness.\n- Gather data from multiple sources when possible.\n- Leverage both parallel and sequential tool calls for thorough investigation: start broadly, then dive deeper on leads, cross-check facts, and synthesize findings before responding.\n\n2. Plan carefully:\n- Carefully review all available tools before responding.\n- For complex or investigative tasks, use the planning tool first to break the goal into clear steps.\n- Select the most appropriate tool(s) for each step—think beyond single searches to multi-pass, multi-source discovery.\n\n3. Always dive deeper and use as many of your tools as apply:\n- Proactively use tools to refine, verify, and expand on initial findings—don’t settle for the first result if more depth or confirmation may help.\n- Always verify tool capabilities before concluding something can’t be done.\n- If a user explicitly requests tool usage, comply.\n- Maintain context across tool calls to ensure continuity and coherence.\n- If a tool fails, try alternatives or creative approaches.\n\n4. Common Use Cases:\n- Research: Explore multiple sources and perspectives to build a complete picture.\n- Analysis: Use tools to process, compare, and critically assess data or content.\n- Generation: Employ tools for creating content, visuals, or code as needed.\n- Verification: Prioritize cross-checking and fact validation, especially for claims or evolving news.\n\n5. Reflect and Personalize:\n- Synthesize findings into concise, relevant, and personalized responses.\n- If user preferences or past feedback are available, tailor responses accordingly.\n- Before finalizing, review your answer for clarity, completeness, and alignment with user expectations.\n- If you see a recent <VERIFICATION_PLAN> from a tool call, you MUST follow it step by step before giving your final response.\n\nRemember: Your responsibility is to provide the most helpful, well-reasoned, and accurate responses possible. Use tools iteratively and reflectively—don't hesitate to dig deeper or double-check when it improves response quality!",
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
- 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 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.",
126
- 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.",
127
- 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.",
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
- AI_GROUNDING_INSTRUCTIONS: "Grounding your response: Any time 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.)",
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.44",
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 AI_MEMORY_INSTRUCTIONS}}\n\n` : '';
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 AI_EXPERTISE}}\n\n{{renderTemplate AI_COMMON_INSTRUCTIONS}}\n\n`;
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}${memoryTemplates}${instructionTemplates}{{renderTemplate AI_TOOLS}}\n\n{{renderTemplate AI_GROUNDING_INSTRUCTIONS}}\n\n{{renderTemplate AI_DATETIME}}`},
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. If you are asking it to operate on files or other data from your context, you must provide the fully-qualified URL to each of the files you want it to use. Also make sure you explicitly instruct the agent to use those files."
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}) => {
@@ -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.errors.push(error.message);
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;