@steno-ai/engine 0.1.4 → 0.1.5
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.
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scratchpad.d.ts","sourceRoot":"","sources":["../../src/scratchpad/scratchpad.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAC7D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AAK1C;;;GAGG;AACH,wBAAsB,aAAa,CACjC,OAAO,EAAE,cAAc,EACvB,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,KAAK,EACZ,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,MAAM,CAAC,CAIjB;AAED;;;GAGG;AACH,wBAAsB,gBAAgB,CACpC,OAAO,EAAE,cAAc,EACvB,GAAG,EAAE,UAAU,EACf,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,KAAK,EACZ,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,EAAE,GACjB,OAAO,CAAC,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"scratchpad.d.ts","sourceRoot":"","sources":["../../src/scratchpad/scratchpad.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAC7D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AAK1C;;;GAGG;AACH,wBAAsB,aAAa,CACjC,OAAO,EAAE,cAAc,EACvB,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,KAAK,EACZ,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,MAAM,CAAC,CAIjB;AAED;;;GAGG;AACH,wBAAsB,gBAAgB,CACpC,OAAO,EAAE,cAAc,EACvB,GAAG,EAAE,UAAU,EACf,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,KAAK,EACZ,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,EAAE,GACjB,OAAO,CAAC,IAAI,CAAC,CAiDf;AA0BD;;;GAGG;AACH,wBAAsB,kBAAkB,CAAC,GAAG,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAyB1F;AAED;;GAEG;AACH,wBAAsB,qBAAqB,CACzC,OAAO,EAAE,cAAc,EACvB,GAAG,EAAE,UAAU,EACf,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,KAAK,EACZ,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,MAAM,CAAC,CAoBjB"}
|
|
@@ -18,12 +18,20 @@ export async function updateScratchpad(storage, llm, tenantId, scope, scopeId, n
|
|
|
18
18
|
return;
|
|
19
19
|
// Get existing scratchpad
|
|
20
20
|
const existing = await getScratchpad(storage, tenantId, scope, scopeId);
|
|
21
|
-
//
|
|
21
|
+
// Merge new facts into existing profile
|
|
22
22
|
const newSection = newFacts.join('\n');
|
|
23
|
-
let updated
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
updated =
|
|
23
|
+
let updated;
|
|
24
|
+
if (!existing) {
|
|
25
|
+
// First scratchpad — just use the new facts
|
|
26
|
+
updated = newSection;
|
|
27
|
+
}
|
|
28
|
+
else if (existing.length + newSection.length < SCRATCHPAD_MAX_CHARS) {
|
|
29
|
+
// Under limit — merge via LLM to keep it clean (not just append)
|
|
30
|
+
updated = await mergeScratchpad(llm, existing, newSection);
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
// Over limit — compress everything together
|
|
34
|
+
updated = await compressScratchpad(llm, `${existing}\n\nNew facts to integrate:\n${newSection}`);
|
|
27
35
|
}
|
|
28
36
|
// Find existing scratchpad fact and invalidate it
|
|
29
37
|
const facts = await storage.getFactsByScope(tenantId, scope, scopeId, { limit: 200 });
|
|
@@ -52,6 +60,28 @@ export async function updateScratchpad(storage, llm, tenantId, scope, scopeId, n
|
|
|
52
60
|
contradictionStatus: 'none',
|
|
53
61
|
});
|
|
54
62
|
}
|
|
63
|
+
/**
|
|
64
|
+
* Merge new facts into an existing scratchpad profile.
|
|
65
|
+
* Integrates new information cleanly without duplicating.
|
|
66
|
+
*/
|
|
67
|
+
async function mergeScratchpad(llm, existing, newFacts) {
|
|
68
|
+
const response = await llm.complete([
|
|
69
|
+
{
|
|
70
|
+
role: 'system',
|
|
71
|
+
content: `You maintain a structured user profile. Merge the new facts into the existing profile.
|
|
72
|
+
|
|
73
|
+
Rules:
|
|
74
|
+
- If a new fact UPDATES an existing one, replace the old version (e.g., "favorite color is now green" replaces "favorite color is blue")
|
|
75
|
+
- If a new fact is already covered, skip it (no duplicates)
|
|
76
|
+
- If a new fact is genuinely new, add it to the appropriate section
|
|
77
|
+
- Keep the profile organized by category (identity, preferences, people, goals, events, etc.)
|
|
78
|
+
- Keep it concise — under ${SCRATCHPAD_MAX_CHARS} characters
|
|
79
|
+
- Output ONLY the merged profile, no explanation`
|
|
80
|
+
},
|
|
81
|
+
{ role: 'user', content: `EXISTING PROFILE:\n${existing}\n\nNEW FACTS TO MERGE:\n${newFacts}` }
|
|
82
|
+
], { temperature: 0 });
|
|
83
|
+
return response.content;
|
|
84
|
+
}
|
|
55
85
|
/**
|
|
56
86
|
* Compress the scratchpad using an LLM.
|
|
57
87
|
* Preserves the most important information while reducing size.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scratchpad.js","sourceRoot":"","sources":["../../src/scratchpad/scratchpad.ts"],"names":[],"mappings":"AAIA,MAAM,oBAAoB,GAAG,IAAI,CAAC;AAClC,MAAM,2BAA2B,GAAG,IAAI,CAAC;AAEzC;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,OAAuB,EACvB,QAAgB,EAChB,KAAY,EACZ,OAAe;IAEf,MAAM,KAAK,GAAG,MAAM,OAAO,CAAC,eAAe,CAAC,QAAQ,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,CAAC;IACtF,MAAM,cAAc,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,QAAQ,CAAC,YAAY,CAAC,CAAC,CAAC;IAC5E,OAAO,cAAc,EAAE,OAAO,IAAI,EAAE,CAAC;AACvC,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,OAAuB,EACvB,GAAe,EACf,QAAgB,EAChB,KAAY,EACZ,OAAe,EACf,QAAkB;IAElB,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO;IAElC,0BAA0B;IAC1B,MAAM,QAAQ,GAAG,MAAM,aAAa,CAAC,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC;IAExE,
|
|
1
|
+
{"version":3,"file":"scratchpad.js","sourceRoot":"","sources":["../../src/scratchpad/scratchpad.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -37,13 +37,19 @@ export async function updateScratchpad(
|
|
|
37
37
|
// Get existing scratchpad
|
|
38
38
|
const existing = await getScratchpad(storage, tenantId, scope, scopeId);
|
|
39
39
|
|
|
40
|
-
//
|
|
40
|
+
// Merge new facts into existing profile
|
|
41
41
|
const newSection = newFacts.join('\n');
|
|
42
|
-
let updated
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
updated =
|
|
42
|
+
let updated: string;
|
|
43
|
+
|
|
44
|
+
if (!existing) {
|
|
45
|
+
// First scratchpad — just use the new facts
|
|
46
|
+
updated = newSection;
|
|
47
|
+
} else if (existing.length + newSection.length < SCRATCHPAD_MAX_CHARS) {
|
|
48
|
+
// Under limit — merge via LLM to keep it clean (not just append)
|
|
49
|
+
updated = await mergeScratchpad(llm, existing, newSection);
|
|
50
|
+
} else {
|
|
51
|
+
// Over limit — compress everything together
|
|
52
|
+
updated = await compressScratchpad(llm, `${existing}\n\nNew facts to integrate:\n${newSection}`);
|
|
47
53
|
}
|
|
48
54
|
|
|
49
55
|
// Find existing scratchpad fact and invalidate it
|
|
@@ -76,6 +82,30 @@ export async function updateScratchpad(
|
|
|
76
82
|
});
|
|
77
83
|
}
|
|
78
84
|
|
|
85
|
+
/**
|
|
86
|
+
* Merge new facts into an existing scratchpad profile.
|
|
87
|
+
* Integrates new information cleanly without duplicating.
|
|
88
|
+
*/
|
|
89
|
+
async function mergeScratchpad(llm: LLMAdapter, existing: string, newFacts: string): Promise<string> {
|
|
90
|
+
const response = await llm.complete([
|
|
91
|
+
{
|
|
92
|
+
role: 'system',
|
|
93
|
+
content: `You maintain a structured user profile. Merge the new facts into the existing profile.
|
|
94
|
+
|
|
95
|
+
Rules:
|
|
96
|
+
- If a new fact UPDATES an existing one, replace the old version (e.g., "favorite color is now green" replaces "favorite color is blue")
|
|
97
|
+
- If a new fact is already covered, skip it (no duplicates)
|
|
98
|
+
- If a new fact is genuinely new, add it to the appropriate section
|
|
99
|
+
- Keep the profile organized by category (identity, preferences, people, goals, events, etc.)
|
|
100
|
+
- Keep it concise — under ${SCRATCHPAD_MAX_CHARS} characters
|
|
101
|
+
- Output ONLY the merged profile, no explanation`
|
|
102
|
+
},
|
|
103
|
+
{ role: 'user', content: `EXISTING PROFILE:\n${existing}\n\nNEW FACTS TO MERGE:\n${newFacts}` }
|
|
104
|
+
], { temperature: 0 });
|
|
105
|
+
|
|
106
|
+
return response.content;
|
|
107
|
+
}
|
|
108
|
+
|
|
79
109
|
/**
|
|
80
110
|
* Compress the scratchpad using an LLM.
|
|
81
111
|
* Preserves the most important information while reducing size.
|