@saltcorn/agents 0.8.5 → 0.8.6
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/consolidate_agent_memory.js +65 -0
- package/index.js +3 -0
- package/package.json +1 -1
- package/skills/LongTermMemory.js +20 -2
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
const FieldRepeat = require("@saltcorn/data/models/fieldrepeat");
|
|
2
|
+
const Table = require("@saltcorn/data/models/table");
|
|
3
|
+
const View = require("@saltcorn/data/models/view");
|
|
4
|
+
const { p } = require("@saltcorn/markup/tags");
|
|
5
|
+
const { get_skills, process_interaction, wrapSegment } = require("./common");
|
|
6
|
+
const { applyAsync } = require("@saltcorn/data/utils");
|
|
7
|
+
const WorkflowRun = require("@saltcorn/data/models/workflow_run");
|
|
8
|
+
const { interpolate, escapeHtml } = require("@saltcorn/data/utils");
|
|
9
|
+
const { getState } = require("@saltcorn/data/db/state");
|
|
10
|
+
|
|
11
|
+
module.exports = {
|
|
12
|
+
//configFields: async ({ table, mode }) => [],
|
|
13
|
+
run: async ({ configuration, user, table, req, ...rest }) => {
|
|
14
|
+
const memtable = Table.findOne("AgentLongTermMemory");
|
|
15
|
+
if (!memtable) return;
|
|
16
|
+
// write personal preferences
|
|
17
|
+
|
|
18
|
+
// get all personal observations
|
|
19
|
+
const personalmems = await memtable.getRows(
|
|
20
|
+
{ personal: true },
|
|
21
|
+
{ orderBy: "written_at" },
|
|
22
|
+
);
|
|
23
|
+
|
|
24
|
+
const user_ids = new Set(personalmems.map((p) => p.user_id));
|
|
25
|
+
|
|
26
|
+
for (const uid of user_ids.values()) {
|
|
27
|
+
const all_umems = personalmems.filter((m) => m.user_id === uid);
|
|
28
|
+
const existingPP = all_umems.find(
|
|
29
|
+
(m) => m.memory_type === "PersonalPreferences",
|
|
30
|
+
);
|
|
31
|
+
const nonPPs = all_umems.filter(
|
|
32
|
+
(m) => m.memory_type !== "PersonalPreferences",
|
|
33
|
+
);
|
|
34
|
+
|
|
35
|
+
if (
|
|
36
|
+
existingPP &&
|
|
37
|
+
nonPPs.every((m) => m.written_at < existingPP.written_at)
|
|
38
|
+
)
|
|
39
|
+
continue; // no new memories
|
|
40
|
+
const prompt = `This is a set of observations about a user:
|
|
41
|
+
${nonPPs.map((m) => `* ${m.contents}`).join("\n")}
|
|
42
|
+
|
|
43
|
+
They are in ascending chronological order so if there are any contradictions, the latter observation take precedence.
|
|
44
|
+
|
|
45
|
+
Write a succinct summary of these observations which captures all the essential facts. Start the summary with the words
|
|
46
|
+
"The user..." (in the language in which the observations appear) and then write what you have learned about the user.`;
|
|
47
|
+
|
|
48
|
+
const answer = await getState().functions.llm_generate.run(prompt);
|
|
49
|
+
|
|
50
|
+
if (answer && typeof answer === "string") {
|
|
51
|
+
await memtable.deleteRows({
|
|
52
|
+
memory_type: "PersonalPreferences",
|
|
53
|
+
user_id: uid,
|
|
54
|
+
});
|
|
55
|
+
await memtable.insertRow({
|
|
56
|
+
user_id: uid,
|
|
57
|
+
written_at: new Date(),
|
|
58
|
+
memory_type: "PersonalPreferences",
|
|
59
|
+
contents: answer,
|
|
60
|
+
personal: true,
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
},
|
|
65
|
+
};
|
package/index.js
CHANGED
|
@@ -36,6 +36,7 @@ module.exports = {
|
|
|
36
36
|
],
|
|
37
37
|
actions: {
|
|
38
38
|
Agent: require("./action"),
|
|
39
|
+
consolidate_agent_memory: require("./consolidate_agent_memory"),
|
|
39
40
|
},
|
|
40
41
|
functions: {
|
|
41
42
|
inspect_agent: {
|
|
@@ -69,6 +70,7 @@ module.exports = {
|
|
|
69
70
|
};
|
|
70
71
|
},
|
|
71
72
|
isAsync: true,
|
|
73
|
+
hidden: true,
|
|
72
74
|
description: "Return system prompt, tools and action of an agent",
|
|
73
75
|
},
|
|
74
76
|
agent_generate: {
|
|
@@ -115,6 +117,7 @@ module.exports = {
|
|
|
115
117
|
};
|
|
116
118
|
},
|
|
117
119
|
isAsync: true,
|
|
120
|
+
hidden: true,
|
|
118
121
|
description: "Run an agent on a prompt",
|
|
119
122
|
arguments: [
|
|
120
123
|
{ name: "agent_name", type: "String" },
|
package/package.json
CHANGED
package/skills/LongTermMemory.js
CHANGED
|
@@ -20,12 +20,23 @@ class LongTermMemory {
|
|
|
20
20
|
Object.assign(this, cfg);
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
-
systemPrompt() {
|
|
23
|
+
async systemPrompt({ user }) {
|
|
24
|
+
let pp = "";
|
|
25
|
+
if (this.inject_personal_prefs && user?.id) {
|
|
26
|
+
const table = Table.findOne("AgentLongTermMemory");
|
|
27
|
+
if (table) {
|
|
28
|
+
const ppRow = await table.getRow({
|
|
29
|
+
memory_type: "PersonalPreferences",
|
|
30
|
+
user_id: user.id,
|
|
31
|
+
});
|
|
32
|
+
if (ppRow) pp = "\n\n" + ppRow.contents;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
24
35
|
return `You have access to a memory bank you can read from or write to. You should search the memory bank with the search_memory tool with any search terms that might be relevant to the user's query or the result of a tool call. When you learn something noteworthy (from the user or from the result of a tool call) store it in memory with the store_in_memory tool. Mark it as personal if it is only true or relevant for the specific user. Don't tell the user when you are storing to and retrieving from memory. ${
|
|
25
36
|
this.add_sys_prompt
|
|
26
37
|
? ` Additional instructions for the memory tools: ${this.add_sys_prompt}`
|
|
27
38
|
: ""
|
|
28
|
-
}`;
|
|
39
|
+
}${pp}`;
|
|
29
40
|
}
|
|
30
41
|
|
|
31
42
|
static async configFields() {
|
|
@@ -36,6 +47,13 @@ class LongTermMemory {
|
|
|
36
47
|
type: "String",
|
|
37
48
|
fieldview: "textarea",
|
|
38
49
|
},
|
|
50
|
+
{
|
|
51
|
+
name: "inject_personal_prefs",
|
|
52
|
+
label: "Personal preferences",
|
|
53
|
+
type: "Bool",
|
|
54
|
+
sublabel:
|
|
55
|
+
"Inject personal preferences generated by the consolidate_agent_memory action in the system prompt",
|
|
56
|
+
},
|
|
39
57
|
];
|
|
40
58
|
}
|
|
41
59
|
|