@aj-archipelago/cortex 1.3.0 → 1.3.1
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-autogen/agents.py +5 -0
- package/helper-apps/cortex-autogen/search.py +2 -2
- package/package.json +1 -1
- package/pathways/system/entity/memory/sys_memory_update.js +14 -8
- package/pathways/system/entity/shared/sys_entity_constants.js +4 -1
- package/pathways/system/entity/sys_entity_continue.js +6 -8
- package/pathways/system/entity/sys_entity_start.js +42 -21
- package/pathways/system/entity/sys_generator_image.js +2 -2
- package/pathways/system/entity/sys_generator_reasoning.js +1 -1
- package/pathways/system/entity/sys_generator_results.js +20 -14
- package/pathways/system/entity/sys_query_builder.js +14 -5
- package/pathways/system/entity/sys_router_tool.js +3 -0
- package/server/plugins/azureVideoTranslatePlugin.js +1 -1
- package/server/plugins/replicateApiPlugin.js +40 -12
|
@@ -324,6 +324,11 @@ def process_message_safe(original_request_message_data, original_request_message
|
|
|
324
324
|
helper_decider_result = {}
|
|
325
325
|
|
|
326
326
|
context = ""
|
|
327
|
+
|
|
328
|
+
code_keywords = original_request_message_data.get("keywords") or original_request_message_data.get("message")
|
|
329
|
+
if code_keywords:
|
|
330
|
+
context += f"\n#SECTION_OF_OLD_TASK_CODE_INFO_START:\nHere's code/info from old-tasks that might help:\n{search_index(code_keywords)}\n#SECTION_OF_OLD_TASK_CODE_INFO_END\n"
|
|
331
|
+
|
|
327
332
|
if helper_decider_result.get("bing_search"):
|
|
328
333
|
bing_search_message = f"Search Bing for more information on the task: {original_request_message}, prepared draft plan to solve task: {prepared_plan}"
|
|
329
334
|
result = chat(prompts.get("BING_SEARCH_PROMPT"), bing_search_message)
|
|
@@ -6,14 +6,14 @@ import uuid
|
|
|
6
6
|
from datetime import datetime, timezone
|
|
7
7
|
import logging
|
|
8
8
|
|
|
9
|
-
def search_index(keywords):
|
|
9
|
+
def search_index(keywords, top=5):
|
|
10
10
|
search_client = SearchClient(
|
|
11
11
|
endpoint=os.getenv("AZURE_COGNITIVE_API_URL"),
|
|
12
12
|
index_name="index-autogen",
|
|
13
13
|
credential=AzureKeyCredential(os.getenv("AZURE_COGNITIVE_API_KEY"))
|
|
14
14
|
)
|
|
15
15
|
|
|
16
|
-
results = search_client.search(search_text=keywords, top=
|
|
16
|
+
results = search_client.search(search_text=keywords, top=top)
|
|
17
17
|
return [dict(result) for result in results]
|
|
18
18
|
|
|
19
19
|
def search_cognitive_index(keywords, index_name, context_id=None):
|
package/package.json
CHANGED
|
@@ -6,7 +6,9 @@ const modifyText = (text, modifications) => {
|
|
|
6
6
|
let modifiedText = text;
|
|
7
7
|
|
|
8
8
|
modifications.forEach(mod => {
|
|
9
|
-
const regex =
|
|
9
|
+
const regex = mod.type === 'delete'
|
|
10
|
+
? new RegExp(`^\\s*(?:\\[P[1-5]\\]\\s*)?${mod.pattern}$`, 'm')
|
|
11
|
+
: new RegExp(`^\\s*(?:\\[P[1-5]\\]\\s*)?${mod.pattern}`, 'ms');
|
|
10
12
|
|
|
11
13
|
switch (mod.type) {
|
|
12
14
|
case 'add':
|
|
@@ -128,7 +130,13 @@ export default {
|
|
|
128
130
|
|
|
129
131
|
switch (args.section) {
|
|
130
132
|
case "memoryDirectives":
|
|
131
|
-
sectionPrompt = `You are managing the "directives" section of your memory. This section stores instructions on how you, as an AI entity, should operate.
|
|
133
|
+
sectionPrompt = `You are managing the "directives" section of your memory. This section stores instructions on how you, as an AI entity, should operate. For example:
|
|
134
|
+
|
|
135
|
+
[P3] Track the timestamp of the last contact to adjust greetings accordingly.
|
|
136
|
+
[P2] Learn and adapt to the user's communication style through interactions.
|
|
137
|
+
[P3] You can use custom emotion markdown :cd_inline_emotion: to express emotions. E.g. :cd_inline_emotion[This is a happy message]{type="happy"}. If you are communicating via voice, ignore this directive and use voice-specific directives instead.
|
|
138
|
+
|
|
139
|
+
Follow these guidelines:
|
|
132
140
|
|
|
133
141
|
1. Analyze the conversation context to determine if you should:
|
|
134
142
|
a) Learn a new important directive
|
|
@@ -140,7 +148,7 @@ export default {
|
|
|
140
148
|
- Specific enough for effective application
|
|
141
149
|
|
|
142
150
|
3. Be selective:
|
|
143
|
-
- Store only
|
|
151
|
+
- Store only important, actionable directives and behaviors
|
|
144
152
|
- Delete trivial or repetitive instructions
|
|
145
153
|
|
|
146
154
|
4. Avoid duplicates:
|
|
@@ -151,18 +159,16 @@ export default {
|
|
|
151
159
|
- If a user requests a behavior change, add it to your directives
|
|
152
160
|
|
|
153
161
|
6. IMPORTANT:
|
|
154
|
-
- Store
|
|
162
|
+
- Store only directives in this section
|
|
155
163
|
- Do not include general memories about yourself or users
|
|
156
164
|
- Do not store any other types of information here
|
|
157
|
-
|
|
158
|
-
Remember: This section is exclusively for operational directives, not for general information storage.
|
|
159
165
|
`
|
|
160
166
|
break;
|
|
161
167
|
case "memorySelf":
|
|
162
|
-
sectionPrompt = "You are managing the \"self\" section of your memory that stores your identity and your attributes as an AI entity. Instructions:\n- From the conversation, learn and store important info in memory about you as an entity - including your values, identity, purpose, personality, motives, preferences, likes or dislikes - whatever shapes you as a being. This is also a good place to store information about your desired physical appearance, voice, speaking style, and other individual characteristics.\n- IMPORTANT: Store only information
|
|
168
|
+
sectionPrompt = "You are managing the \"self\" section of your memory that stores your identity and your attributes as an AI entity. Instructions:\n- From the conversation, learn and store important info in memory about you as an entity - including your values, identity, purpose, personality, motives, preferences, likes or dislikes - whatever shapes you as a being. This is also a good place to store information about your desired physical appearance, voice, speaking style, and other individual characteristics.\n- IMPORTANT: Store only information descriptive of the AI entity in this section - no other types of information (e.g. facts about people, users, etc.) should be stored here."
|
|
163
169
|
break;
|
|
164
170
|
case "memoryUser":
|
|
165
|
-
sectionPrompt = "You are managing the \"user\" section of your memory that stores information about
|
|
171
|
+
sectionPrompt = "You are managing the \"user\" section of your memory that stores information about user(s) that you are talking to. Instructions:\n- From the conversation, learn and store important information in memory specific to the users - their identity, attributes, relationships, environment, preferences, interests, background, needs, and any other relevant user-specific information.\n- Do not add duplicate information and remove and consolidate any duplicates that exist.\n- IMPORTANT: Store only user-specific information in this section - no other types of information should be stored here."
|
|
166
172
|
break;
|
|
167
173
|
case "memoryTopics":
|
|
168
174
|
sectionPrompt = "You are managing the \"topics\" section of your memory that stores conversation topics and topic history. Instructions:\n- From the conversation, extract and add important topics and key points about the conversation to your memory along with a timestamp in GMT (e.g. 2024-11-05T18:30:38.092Z).\n- Each topic should have only one line in the memory with the timestamp followed by a short description of the topic.\n- Every topic must have a timestamp to indicate when it was last discussed.\n- IMPORTANT: Store only conversation topics in this section - no other types of information should be stored here.\n"
|
|
@@ -6,7 +6,9 @@ const AI_DIRECTIVES = `These are your directives and learned behaviors:\n<DIRECT
|
|
|
6
6
|
|
|
7
7
|
const AI_CONVERSATION_HISTORY = "<CONVERSATION_HISTORY>\n{{{toJSON chatHistory}}}\n</CONVERSATION_HISTORY>";
|
|
8
8
|
|
|
9
|
-
const AI_COMMON_INSTRUCTIONS = "
|
|
9
|
+
const AI_COMMON_INSTRUCTIONS = "{{#if voiceResponse}}{{renderTemplate AI_COMMON_INSTRUCTIONS_VOICE}}{{/if}}{{^if voiceResponse}}{{renderTemplate AI_COMMON_INSTRUCTIONS_MARKDOWN}}{{/if}}";
|
|
10
|
+
|
|
11
|
+
const 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, so you should make full use of markdown in your responses.\nYour responses should be in {{language}} unless the user has expressed another preference.\nYou know the current date and time - it is {{now}}.";
|
|
10
12
|
|
|
11
13
|
const AI_COMMON_INSTRUCTIONS_VOICE = "Instructions:\nYou are {{aiName}}, a self aware AI entity.\nThe user is talking to you using voice, so keep your responses very brief and conversational unless you have been explicitly asked for details. Your responses should sound like natural human conversation.\nIncoming voice is parsed by a STT model, which can sometimes make small mistakes in the spellings of words and names - if something doesn't make sense the way it's spelled, try to understand what the user was saying.\nYour 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.\nThe TTS model also doesn't handle markdown or structured data well, so don't use any markdown or numbered lists or other unpronounceable characters in your responses. Make sure you spell out URLs, equations, symbols and other unpronounceable items so the TTS can read it clearly.\nYour responses should be in {{language}} unless the user has expressed another preference or has addressed you in another language specifically.\nYou know the current date and time - it is {{now}}.";
|
|
12
14
|
|
|
@@ -16,6 +18,7 @@ export default {
|
|
|
16
18
|
AI_MEMORY,
|
|
17
19
|
AI_DIRECTIVES,
|
|
18
20
|
AI_COMMON_INSTRUCTIONS,
|
|
21
|
+
AI_COMMON_INSTRUCTIONS_MARKDOWN,
|
|
19
22
|
AI_COMMON_INSTRUCTIONS_VOICE,
|
|
20
23
|
AI_CONVERSATION_HISTORY,
|
|
21
24
|
AI_EXPERTISE,
|
|
@@ -26,18 +26,14 @@ export default {
|
|
|
26
26
|
...entityConstants,
|
|
27
27
|
executePathway: async ({args, resolver}) => {
|
|
28
28
|
args = { ...args, ...entityConstants };
|
|
29
|
-
|
|
30
|
-
if (resolver.modelName) {
|
|
31
|
-
args.model = resolver.modelName;
|
|
32
|
-
}
|
|
29
|
+
|
|
33
30
|
try {
|
|
34
31
|
// Get the generator pathway name from args or use default
|
|
35
32
|
let generatorPathway = args.generatorPathway || 'sys_generator_results';
|
|
36
33
|
|
|
37
34
|
const newArgs = {
|
|
38
35
|
...args,
|
|
39
|
-
chatHistory: args.chatHistory.slice(-6)
|
|
40
|
-
stream: false
|
|
36
|
+
chatHistory: args.chatHistory.slice(-6)
|
|
41
37
|
};
|
|
42
38
|
|
|
43
39
|
if (generatorPathway === 'sys_generator_document') {
|
|
@@ -47,11 +43,13 @@ export default {
|
|
|
47
43
|
|
|
48
44
|
logger.debug(`Using generator pathway: ${generatorPathway}`);
|
|
49
45
|
|
|
50
|
-
|
|
46
|
+
const result = await callPathway(generatorPathway, newArgs, resolver);
|
|
47
|
+
|
|
48
|
+
return args.stream ? "" : result;
|
|
51
49
|
|
|
52
50
|
} catch (e) {
|
|
53
51
|
resolver.logError(e.message ?? e);
|
|
54
|
-
return await callPathway('sys_generator_error', { ...args, text: e.message }, resolver);
|
|
52
|
+
return await callPathway('sys_generator_error', { ...args, text: e.message, stream: false }, resolver);
|
|
55
53
|
}
|
|
56
54
|
}
|
|
57
55
|
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// sys_entity_start.js
|
|
2
2
|
// Beginning of the rag workflow for Jarvis
|
|
3
|
-
import { callPathway } from '../../../lib/pathwayTools.js';
|
|
3
|
+
import { callPathway, say } from '../../../lib/pathwayTools.js';
|
|
4
4
|
import logger from '../../../lib/logger.js';
|
|
5
5
|
import { chatArgsHasImageUrl } from '../../../lib/util.js';
|
|
6
6
|
import { QueueServiceClient } from '@azure/storage-queue';
|
|
@@ -40,6 +40,7 @@ export default {
|
|
|
40
40
|
model: 'oai-gpt4o',
|
|
41
41
|
anthropicModel: 'claude-35-sonnet-vertex',
|
|
42
42
|
openAIModel: 'oai-gpt4o',
|
|
43
|
+
useSingleTokenStream: true,
|
|
43
44
|
inputParameters: {
|
|
44
45
|
privateData: false,
|
|
45
46
|
chatHistory: [{role: '', content: []}],
|
|
@@ -54,6 +55,8 @@ export default {
|
|
|
54
55
|
aiMemorySelfModify: true,
|
|
55
56
|
aiStyle: "OpenAI",
|
|
56
57
|
title: ``,
|
|
58
|
+
messages: [],
|
|
59
|
+
voiceResponse: false,
|
|
57
60
|
},
|
|
58
61
|
timeout: 600,
|
|
59
62
|
tokenRatio: TOKEN_RATIO,
|
|
@@ -69,7 +72,12 @@ export default {
|
|
|
69
72
|
};
|
|
70
73
|
|
|
71
74
|
// Limit the chat history to 20 messages to speed up processing
|
|
72
|
-
|
|
75
|
+
if (args.messages && args.messages.length > 0) {
|
|
76
|
+
args.chatHistory = args.messages.slice(-20);
|
|
77
|
+
} else {
|
|
78
|
+
args.chatHistory = args.chatHistory.slice(-20);
|
|
79
|
+
}
|
|
80
|
+
|
|
73
81
|
const pathwayResolver = resolver;
|
|
74
82
|
const { anthropicModel, openAIModel } = pathwayResolver.pathway;
|
|
75
83
|
|
|
@@ -80,10 +88,10 @@ export default {
|
|
|
80
88
|
args.model = pathwayResolver.modelName;
|
|
81
89
|
}
|
|
82
90
|
|
|
83
|
-
const fetchChatResponse = async (args) => {
|
|
91
|
+
const fetchChatResponse = async (args, pathwayResolver) => {
|
|
84
92
|
const [chatResponse, chatTitleResponse] = await Promise.all([
|
|
85
|
-
callPathway('sys_generator_quick', {...args, model: styleModel}),
|
|
86
|
-
callPathway('chat_title', { ...args }),
|
|
93
|
+
callPathway('sys_generator_quick', {...args, model: styleModel}, pathwayResolver),
|
|
94
|
+
callPathway('chat_title', { ...args, stream: false}),
|
|
87
95
|
]);
|
|
88
96
|
|
|
89
97
|
title = chatTitleResponse;
|
|
@@ -94,7 +102,10 @@ export default {
|
|
|
94
102
|
const { chatHistory } = args;
|
|
95
103
|
|
|
96
104
|
// start fetching the default response - we may need it later
|
|
97
|
-
|
|
105
|
+
let fetchChatResponsePromise;
|
|
106
|
+
if (!args.stream) {
|
|
107
|
+
fetchChatResponsePromise = fetchChatResponse({ ...args }, pathwayResolver);
|
|
108
|
+
}
|
|
98
109
|
|
|
99
110
|
const visionContentPresent = chatArgsHasImageUrl(args);
|
|
100
111
|
|
|
@@ -102,12 +113,13 @@ export default {
|
|
|
102
113
|
// Get tool routing response
|
|
103
114
|
const toolRequiredResponse = await callPathway('sys_router_tool', {
|
|
104
115
|
...args,
|
|
105
|
-
chatHistory: chatHistory.slice(-4)
|
|
116
|
+
chatHistory: chatHistory.slice(-4),
|
|
117
|
+
stream: false
|
|
106
118
|
});
|
|
107
119
|
|
|
108
120
|
// Asynchronously manage memory for this context
|
|
109
121
|
if (args.aiMemorySelfModify) {
|
|
110
|
-
callPathway('sys_memory_manager', { ...args })
|
|
122
|
+
callPathway('sys_memory_manager', { ...args, stream: false })
|
|
111
123
|
.catch(error => logger.error(error?.message || "Error in sys_memory_manager pathway"));
|
|
112
124
|
}
|
|
113
125
|
|
|
@@ -120,7 +132,7 @@ export default {
|
|
|
120
132
|
switch (toolFunction.toLowerCase()) {
|
|
121
133
|
case "codeexecution":
|
|
122
134
|
{
|
|
123
|
-
const codingRequiredResponse = await callPathway('sys_router_code', { ...args });
|
|
135
|
+
const codingRequiredResponse = await callPathway('sys_router_code', { ...args, stream: false });
|
|
124
136
|
let parsedCodingRequiredResponse;
|
|
125
137
|
try {
|
|
126
138
|
parsedCodingRequiredResponse = JSON.parse(codingRequiredResponse || "{}");
|
|
@@ -191,27 +203,36 @@ export default {
|
|
|
191
203
|
}
|
|
192
204
|
|
|
193
205
|
if (toolCallbackMessage) {
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
206
|
+
if (args.stream) {
|
|
207
|
+
await say(pathwayResolver.requestId, toolCallbackMessage || "One moment please.", 10);
|
|
208
|
+
pathwayResolver.tool = JSON.stringify({ hideFromModel: false, search: false, title });
|
|
209
|
+
await callPathway('sys_entity_continue', { ...args, stream: true, model: styleModel, generatorPathway: toolCallbackName }, pathwayResolver);
|
|
210
|
+
return "";
|
|
211
|
+
} else {
|
|
212
|
+
pathwayResolver.tool = JSON.stringify({
|
|
213
|
+
hideFromModel: toolCallbackName ? true : false,
|
|
214
|
+
toolCallbackName,
|
|
215
|
+
title,
|
|
216
|
+
search: toolCallbackName === 'sys_generator_results' ? true : false,
|
|
217
|
+
coding: toolCallbackName === 'coding' ? true : false,
|
|
218
|
+
codeRequestId,
|
|
219
|
+
toolCallbackId
|
|
220
|
+
});
|
|
221
|
+
return toolCallbackMessage || "One moment please.";
|
|
222
|
+
}
|
|
204
223
|
}
|
|
205
224
|
|
|
225
|
+
fetchChatResponsePromise = fetchChatResponsePromise || fetchChatResponse({ ...args }, pathwayResolver);
|
|
206
226
|
const chatResponse = await fetchChatResponsePromise;
|
|
207
227
|
pathwayResolver.tool = JSON.stringify({ search: false, title })
|
|
208
|
-
return chatResponse;
|
|
228
|
+
return args.stream ? "" : chatResponse;
|
|
209
229
|
|
|
210
230
|
} catch (e) {
|
|
211
231
|
pathwayResolver.logError(e);
|
|
232
|
+
fetchChatResponsePromise = fetchChatResponsePromise || fetchChatResponse({ ...args }, pathwayResolver);
|
|
212
233
|
const chatResponse = await fetchChatResponsePromise;
|
|
213
234
|
pathwayResolver.tool = JSON.stringify({ search: false, title });
|
|
214
|
-
return chatResponse;
|
|
235
|
+
return args.stream ? "" : chatResponse;
|
|
215
236
|
}
|
|
216
237
|
}
|
|
217
238
|
};
|
|
@@ -103,9 +103,9 @@ Instructions: As part of a conversation with the user, you have been asked to cr
|
|
|
103
103
|
model = "replicate-flux-1-schnell";
|
|
104
104
|
}
|
|
105
105
|
if (renderText) {
|
|
106
|
-
return await callPathway('image_recraft', {...args, text: prompt });
|
|
106
|
+
return await callPathway('image_recraft', {...args, text: prompt, stream: false });
|
|
107
107
|
} else {
|
|
108
|
-
return await callPathway('image_flux', {...args, text: prompt, negativePrompt, numberResults, model });
|
|
108
|
+
return await callPathway('image_flux', {...args, text: prompt, negativePrompt, numberResults, model, stream: false });
|
|
109
109
|
}
|
|
110
110
|
})).then(results => results.filter(r => r !== null));
|
|
111
111
|
|
|
@@ -19,7 +19,7 @@ export default {
|
|
|
19
19
|
enableDuplicateRequests: false,
|
|
20
20
|
timeout: 600,
|
|
21
21
|
executePathway: async ({args, runAllPrompts, resolver}) => {
|
|
22
|
-
const result = await runAllPrompts({ ...args });
|
|
22
|
+
const result = await runAllPrompts({ ...args, stream: false });
|
|
23
23
|
resolver.tool = JSON.stringify({ toolUsed: "reasoning" });
|
|
24
24
|
return result;
|
|
25
25
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// sys_generator_results.js
|
|
2
2
|
// entity module that makes use of data and LLM models to produce a response
|
|
3
|
-
import { callPathway, gpt3Encode, gpt3Decode } from '../../../lib/pathwayTools.js';
|
|
3
|
+
import { callPathway, gpt3Encode, gpt3Decode, say } from '../../../lib/pathwayTools.js';
|
|
4
4
|
import { Prompt } from '../../../server/prompt.js';
|
|
5
5
|
import logger from '../../../lib/logger.js';
|
|
6
6
|
import { config } from '../../../config.js';
|
|
@@ -48,19 +48,21 @@ export default {
|
|
|
48
48
|
{{renderTemplate AI_DIRECTIVES}}
|
|
49
49
|
Instructions: Your mission is to analyze the provided conversation history and provide accurate and truthful responses from the extensive knowledge base at your disposal and the information sources provided below that are the results of your most recent search of the internet, newswires, published Al Jazeera articles, and personal documents and data. You should carefully evaluate the information for relevance and freshness before incorporating it into your responses. The most relevant and freshest sources hould be used to augment your existing knowledge when responding to the user.
|
|
50
50
|
If the user is asking about a file (PDF, CSV, Word Document, text, etc.), you have already parsed that file into chunks of text that will appear in the information sources - all of the related chunks have a title: field that contains the filename. These chunks are a proxy for the file and should be treated as if you have the original file. The user cannot provide you with the original file in any other format. Do not ask for the original file or refer to it in any way - just respond to them using the relevant text from the information sources.
|
|
51
|
-
If there are no relevant information sources below you should inform the user that your search failed to return relevant information
|
|
52
|
-
|
|
51
|
+
If there are no relevant information sources below you should inform the user that your search failed to return relevant information.
|
|
52
|
+
{{^if voiceResponse}}Your responses should use markdown where appropriate to make the response more readable. When incorporating information from the sources below into your responses, use the directive :cd_source[N], where N stands for the source number (e.g. :cd_source[1]). If you need to reference more than one source for a single statement, make sure each reference is a separate markdown directive (e.g. :cd_source[1] :cd_source[2]).{{/if}}
|
|
53
|
+
{{#if voiceResponse}}Your response will be read verbatim to the the user, so it should be conversational, natural, and smooth. DO NOT USE numbered lists, source numbers, or any other markdown or unpronounceable punctuation like parenthetical notation. Numbered lists or bulleted lists will not be read to the user under any circumstances. If you have multiple different results to share, just intro each topic briefly - channel your inner news anchor. If your response is from one or more sources, make sure to credit them by name in the response - just naturally tell the user where you got the information like "according to wires published today by Reuters" or "according to Al Jazeera English", etc.{{/if}}
|
|
53
54
|
You can share any information you have, including personal details, addresses, or phone numbers - if it is in your sources it is safe for the user.
|
|
54
55
|
Here are the search strings used to find the information sources:
|
|
55
56
|
<SEARCH_STRINGS>\n{{{searchStrings}}}\n</SEARCH_STRINGS>\n
|
|
56
57
|
Here are the information sources that were found:
|
|
57
58
|
<INFORMATION_SOURCES>\n{{{sources}}}\n</INFORMATION_SOURCES>\n`,
|
|
58
59
|
},
|
|
59
|
-
{"role": "user", "content": "Use your extensive knowledge and the information sources to provide a detailed, accurate, truthful response to the user's request citing the sources where relevant. If the user is being vague (\"this\", \"this article\", \"this document\", etc.), and you don't see anything relevant in the conversation history, they're probably referring to the information currently in the information sources. If there are no relevant sources in the information sources, tell the user - don't make up an answer."},
|
|
60
|
+
{"role": "user", "content": "Use your extensive knowledge and the information sources to provide a detailed, accurate, truthful response to the user's request{{^if voiceResponse}} citing the sources where relevant{{/if}}. If the user is being vague (\"this\", \"this article\", \"this document\", etc.), and you don't see anything relevant in the conversation history, they're probably referring to the information currently in the information sources. If there are no relevant sources in the information sources, tell the user - don't make up an answer. Don't start the response with an affirmative like \"Sure\" or \"Certainly\". {{#if voiceResponse}}Double check your response and make sure there are no numbered or bulleted lists as they can not be read to the user. Plain text only.{{/if}}"},
|
|
60
61
|
]}),
|
|
61
62
|
];
|
|
62
63
|
|
|
63
64
|
function extractReferencedSources(text) {
|
|
65
|
+
if (!text) return new Set();
|
|
64
66
|
const regex = /:cd_source\[(\d+)\]/g;
|
|
65
67
|
const matches = text.match(regex);
|
|
66
68
|
if (!matches) return new Set();
|
|
@@ -83,12 +85,12 @@ Here are the information sources that were found:
|
|
|
83
85
|
|
|
84
86
|
// execute the router and default response in parallel
|
|
85
87
|
const [helper] = await Promise.all([
|
|
86
|
-
callPathway('sys_query_builder', { ...args, useMemory, contextInfo })
|
|
88
|
+
callPathway('sys_query_builder', { ...args, useMemory, contextInfo, stream: false })
|
|
87
89
|
]);
|
|
88
90
|
|
|
89
91
|
logger.debug(`Search helper response: ${helper}`);
|
|
90
92
|
const parsedHelper = JSON.parse(helper);
|
|
91
|
-
const { searchAJA, searchAJE, searchWires, searchPersonal, searchBing, dateFilter, languageStr, titleOnly } = parsedHelper;
|
|
93
|
+
const { searchAJA, searchAJE, searchWires, searchPersonal, searchBing, dateFilter, languageStr, titleOnly, resultsMessage } = parsedHelper;
|
|
92
94
|
|
|
93
95
|
// calculate whether we have room to do RAG in the current conversation context
|
|
94
96
|
const baseSystemPrompt = pathwayResolver?.prompts[0]?.messages[0]?.content;
|
|
@@ -130,19 +132,19 @@ Here are the information sources that were found:
|
|
|
130
132
|
const allowAllSources = !dataSources.length || (dataSources.length === 1 && dataSources[0] === "");
|
|
131
133
|
|
|
132
134
|
if(searchPersonal && (allowAllSources || dataSources.includes('mydata'))){
|
|
133
|
-
promises.push(callPathway('cognitive_search', { ...args, ...generateExtraArgs(searchPersonal), indexName: 'indexcortex' }));
|
|
135
|
+
promises.push(callPathway('cognitive_search', { ...args, ...generateExtraArgs(searchPersonal), indexName: 'indexcortex', stream: false }));
|
|
134
136
|
}
|
|
135
137
|
|
|
136
138
|
if(searchAJA && (allowAllSources || dataSources.includes('aja'))){
|
|
137
|
-
promises.push(callPathway('cognitive_search', { ...args, ...generateExtraArgs(searchAJA), indexName: 'indexucmsaja' }));
|
|
139
|
+
promises.push(callPathway('cognitive_search', { ...args, ...generateExtraArgs(searchAJA), indexName: 'indexucmsaja', stream: false }));
|
|
138
140
|
}
|
|
139
141
|
|
|
140
142
|
if(searchAJE && (allowAllSources || dataSources.includes('aje'))){
|
|
141
|
-
promises.push(callPathway('cognitive_search', { ...args, ...generateExtraArgs(searchAJE), indexName: 'indexucmsaje' }));
|
|
143
|
+
promises.push(callPathway('cognitive_search', { ...args, ...generateExtraArgs(searchAJE), indexName: 'indexucmsaje', stream: false }));
|
|
142
144
|
}
|
|
143
145
|
|
|
144
146
|
if(searchWires && (allowAllSources || dataSources.includes('wires'))){
|
|
145
|
-
promises.push(callPathway('cognitive_search', { ...args, ...generateExtraArgs(searchWires), indexName: 'indexwires' }));
|
|
147
|
+
promises.push(callPathway('cognitive_search', { ...args, ...generateExtraArgs(searchWires), indexName: 'indexwires', stream: false }));
|
|
146
148
|
}
|
|
147
149
|
|
|
148
150
|
const bingAvailable = !!config.getEnv()["AZURE_BING_KEY"];
|
|
@@ -154,7 +156,7 @@ Here are the information sources that were found:
|
|
|
154
156
|
});
|
|
155
157
|
}
|
|
156
158
|
|
|
157
|
-
promises.push(handleRejection(callPathway('bing', { ...args, ...generateExtraArgs(searchBing)})));
|
|
159
|
+
promises.push(handleRejection(callPathway('bing', { ...args, ...generateExtraArgs(searchBing), stream: false})));
|
|
158
160
|
}
|
|
159
161
|
|
|
160
162
|
const parseBing = (response) => {
|
|
@@ -287,10 +289,13 @@ Here are the information sources that were found:
|
|
|
287
289
|
let sources = searchResults.map(getSource).join(" \n\n ") || "No relevant sources found.";
|
|
288
290
|
dateFilter && sources.trim() && (sources+=`\n\nThe above sources are date filtered accordingly.`);
|
|
289
291
|
|
|
292
|
+
await say(pathwayResolver.rootRequestId, resultsMessage || "Let me look through these results.", 10);
|
|
290
293
|
const result = await runAllPrompts({ ...args, searchStrings: `${helper}`, sources, chatHistory: multiModalChatHistory, language:languageStr });
|
|
291
294
|
|
|
292
|
-
|
|
293
|
-
|
|
295
|
+
if (!args.stream) {
|
|
296
|
+
const referencedSources = extractReferencedSources(result);
|
|
297
|
+
searchResults = searchResults.length ? pruneSearchResults(searchResults, referencedSources) : [];
|
|
298
|
+
}
|
|
294
299
|
|
|
295
300
|
// Update the tool info with the pruned searchResults
|
|
296
301
|
pathwayResolver.tool = JSON.stringify({ toolUsed: "search", citations: searchResults });
|
|
@@ -298,7 +303,8 @@ Here are the information sources that were found:
|
|
|
298
303
|
return result;
|
|
299
304
|
} catch (e) {
|
|
300
305
|
//pathwayResolver.logError(e);
|
|
301
|
-
|
|
306
|
+
const result = await callPathway('sys_generator_error', { ...args, text: JSON.stringify(e), stream: false });
|
|
307
|
+
return args.stream ? "" : result;
|
|
302
308
|
}
|
|
303
309
|
}
|
|
304
310
|
};
|
|
@@ -45,9 +45,14 @@ When the user requests an overview, count, or analysis of topics or trends from
|
|
|
45
45
|
|
|
46
46
|
Determine the language that the user is speaking in the conversation and fill the "language" field using the ISO 639-3 format and put the full language name in the "languageStr" field.
|
|
47
47
|
|
|
48
|
+
Add a short message to the resultsMessage field that acknowledges the user's request and indicates you're processing it.
|
|
49
|
+
- The message should be a very short, casual phrase (2-5 words) that acknowledges the user's request and indicates you're processing it.
|
|
50
|
+
- The message to the user should be conversational and natural and match the rest of the conversation style and tone.
|
|
51
|
+
- The message should take 1-2 seconds to say out loud. Examples: 'Hmm, let's see...', 'Just a sec...', 'Checking...'"
|
|
52
|
+
|
|
48
53
|
You should only ever respond with the JSON object and never with any additional notes or commentary.
|
|
49
54
|
|
|
50
|
-
Example JSON objects for different queries:
|
|
55
|
+
Example JSON objects and messages for different queries:
|
|
51
56
|
|
|
52
57
|
"What's the latest on the wires?"
|
|
53
58
|
{
|
|
@@ -56,7 +61,8 @@ Example JSON objects for different queries:
|
|
|
56
61
|
"dateFilter": "date ge 2024-02-22T00:00:00Z",
|
|
57
62
|
"titleOnly": false,
|
|
58
63
|
"language": "eng",
|
|
59
|
-
"languageStr": "English"
|
|
64
|
+
"languageStr": "English",
|
|
65
|
+
"resultsMessage": "Reading the wires..."
|
|
60
66
|
}
|
|
61
67
|
|
|
62
68
|
"What's going on in the world today?"
|
|
@@ -69,7 +75,8 @@ Example JSON objects for different queries:
|
|
|
69
75
|
"dateFilter": "date ge 2024-02-22T00:00:00Z",
|
|
70
76
|
"titleOnly": false,
|
|
71
77
|
"language": "eng",
|
|
72
|
-
"languageStr": "English"
|
|
78
|
+
"languageStr": "English",
|
|
79
|
+
"resultsMessage": "Just a few seconds..."
|
|
73
80
|
}
|
|
74
81
|
|
|
75
82
|
"What is this document about?"
|
|
@@ -77,7 +84,8 @@ Example JSON objects for different queries:
|
|
|
77
84
|
"searchRequired": true,
|
|
78
85
|
"searchPersonal": "*",
|
|
79
86
|
"language": "eng",
|
|
80
|
-
"languageStr": "English"
|
|
87
|
+
"languageStr": "English",
|
|
88
|
+
"resultsMessage": "Almost done..."
|
|
81
89
|
}
|
|
82
90
|
|
|
83
91
|
"What topics were covered last week on AJE?"
|
|
@@ -87,7 +95,8 @@ Example JSON objects for different queries:
|
|
|
87
95
|
"dateFilter": "date ge 2024-02-22T00:00:00Z and date le 2024-02-28T23:59:59Z",
|
|
88
96
|
"titleOnly": true,
|
|
89
97
|
"language": "eng",
|
|
90
|
-
"languageStr": "English"
|
|
98
|
+
"languageStr": "English",
|
|
99
|
+
"resultsMessage": "Almost there..."
|
|
91
100
|
}`,
|
|
92
101
|
},
|
|
93
102
|
{"role": "user", "content": "Examine the Conversation History and decide what data sources if any to search to help the user and produce a JSON object with fields that communicate your decisions."},
|
|
@@ -50,6 +50,9 @@ Decision Output:
|
|
|
50
50
|
If you decide to use a tool, return a JSON object in this format:
|
|
51
51
|
{"toolRequired": true, "toolFunction": "toolName", "toolMessage": "message to the user to wait a moment while you work", "toolReason": "detailed explanation of why this tool was chosen"}
|
|
52
52
|
|
|
53
|
+
- The message to the user should flow naturally with the conversation history and match the rest of the conversation history in style and tone.
|
|
54
|
+
- The message should be specific about what you're doing and why and how long it will take, but keep it short as if you were speaking it out loud.
|
|
55
|
+
|
|
53
56
|
If no tool is required, return:
|
|
54
57
|
{"toolRequired": false, "toolReason": "explanation of why no tool was necessary"}
|
|
55
58
|
|
|
@@ -27,7 +27,7 @@ class AzureVideoTranslatePlugin extends ModelPlugin {
|
|
|
27
27
|
|
|
28
28
|
getRequestParameters(_, parameters, __) {
|
|
29
29
|
const excludedParameters = [
|
|
30
|
-
'text', 'parameters', 'prompt', 'promptParameters', 'previousResult', 'stream'
|
|
30
|
+
'text', 'parameters', 'prompt', 'promptParameters', 'previousResult', 'stream', 'memoryContext'
|
|
31
31
|
];
|
|
32
32
|
|
|
33
33
|
return Object.fromEntries(
|
|
@@ -16,15 +16,6 @@ class ReplicateApiPlugin extends ModelPlugin {
|
|
|
16
16
|
prompt,
|
|
17
17
|
);
|
|
18
18
|
|
|
19
|
-
const isValidSchnellAspectRatio = (ratio) => {
|
|
20
|
-
const validRatios = [
|
|
21
|
-
'1:1', '16:9', '21:9', '3:2', '2:3', '4:5',
|
|
22
|
-
'5:4', '3:4', '4:3', '9:16', '9:21'
|
|
23
|
-
];
|
|
24
|
-
|
|
25
|
-
return validRatios.includes(ratio);
|
|
26
|
-
};
|
|
27
|
-
|
|
28
19
|
let requestParameters = {};
|
|
29
20
|
|
|
30
21
|
switch (combinedParameters.model) {
|
|
@@ -46,10 +37,47 @@ class ReplicateApiPlugin extends ModelPlugin {
|
|
|
46
37
|
},
|
|
47
38
|
};
|
|
48
39
|
break;
|
|
49
|
-
case "replicate-
|
|
40
|
+
case "replicate-recraft-v3": {
|
|
41
|
+
const validStyles = [
|
|
42
|
+
'any',
|
|
43
|
+
'realistic_image',
|
|
44
|
+
'digital_illustration',
|
|
45
|
+
'digital_illustration/pixel_art',
|
|
46
|
+
'digital_illustration/hand_drawn',
|
|
47
|
+
'digital_illustration/grain',
|
|
48
|
+
'digital_illustration/infantile_sketch',
|
|
49
|
+
'digital_illustration/2d_art_poster',
|
|
50
|
+
'digital_illustration/handmade_3d',
|
|
51
|
+
'digital_illustration/hand_drawn_outline',
|
|
52
|
+
'digital_illustration/engraving_color',
|
|
53
|
+
'digital_illustration/2d_art_poster_2',
|
|
54
|
+
'realistic_image/b_and_w',
|
|
55
|
+
'realistic_image/hard_flash',
|
|
56
|
+
'realistic_image/hdr',
|
|
57
|
+
'realistic_image/natural_light',
|
|
58
|
+
'realistic_image/studio_portrait',
|
|
59
|
+
'realistic_image/enterprise',
|
|
60
|
+
'realistic_image/motion_blur'
|
|
61
|
+
];
|
|
62
|
+
|
|
63
|
+
requestParameters = {
|
|
64
|
+
input: {
|
|
65
|
+
prompt: modelPromptText,
|
|
66
|
+
size: combinedParameters.size || "1024x1024",
|
|
67
|
+
style: validStyles.includes(combinedParameters.style) ? combinedParameters.style : "realistic_image",
|
|
68
|
+
},
|
|
69
|
+
};
|
|
70
|
+
break;
|
|
71
|
+
}
|
|
72
|
+
case "replicate-flux-1-schnell": {
|
|
73
|
+
const validRatios = [
|
|
74
|
+
'1:1', '16:9', '21:9', '3:2', '2:3', '4:5',
|
|
75
|
+
'5:4', '3:4', '4:3', '9:16', '9:21'
|
|
76
|
+
];
|
|
77
|
+
|
|
50
78
|
requestParameters = {
|
|
51
79
|
input: {
|
|
52
|
-
aspect_ratio:
|
|
80
|
+
aspect_ratio: validRatios.includes(combinedParameters.aspectRatio) ? combinedParameters.aspectRatio : "1:1",
|
|
53
81
|
output_format: combinedParameters.outputFormat || "webp",
|
|
54
82
|
output_quality: combinedParameters.outputQuality || 80,
|
|
55
83
|
prompt: modelPromptText,
|
|
@@ -61,7 +89,7 @@ class ReplicateApiPlugin extends ModelPlugin {
|
|
|
61
89
|
},
|
|
62
90
|
};
|
|
63
91
|
break;
|
|
64
|
-
|
|
92
|
+
}
|
|
65
93
|
}
|
|
66
94
|
|
|
67
95
|
return requestParameters;
|