pi-observational-memory 1.0.3 → 2.1.0
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/README.md +79 -104
- package/package.json +1 -1
- package/src/branch.ts +190 -0
- package/src/commands/status.ts +80 -0
- package/src/commands/view.ts +79 -0
- package/src/compaction.ts +331 -0
- package/src/config.ts +6 -4
- package/src/hooks/compaction-hook.ts +201 -0
- package/src/hooks/compaction-trigger.ts +68 -0
- package/src/hooks/observer-trigger.ts +89 -0
- package/src/ids.ts +5 -0
- package/src/index.ts +12 -333
- package/src/observer.ts +143 -0
- package/src/prompts.ts +270 -168
- package/src/relevance.ts +15 -0
- package/src/runtime.ts +76 -0
- package/src/serialize.ts +103 -0
- package/src/tokens.ts +16 -41
- package/src/types.ts +56 -7
package/src/tokens.ts
CHANGED
|
@@ -1,52 +1,27 @@
|
|
|
1
1
|
import { estimateTokens as estimateMessageTokens } from "@mariozechner/pi-coding-agent";
|
|
2
2
|
|
|
3
|
-
export function
|
|
3
|
+
export function estimateStringTokens(text: string): number {
|
|
4
4
|
return Math.ceil(text.length / 4);
|
|
5
5
|
}
|
|
6
6
|
|
|
7
|
-
export function
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
let startIndex = 0;
|
|
11
|
-
for (let i = entries.length - 1; i >= 0; i--) {
|
|
12
|
-
if (entries[i].type === "compaction") {
|
|
13
|
-
const keptId = entries[i].firstKeptEntryId;
|
|
14
|
-
if (keptId) {
|
|
15
|
-
for (let j = 0; j < entries.length; j++) {
|
|
16
|
-
if (entries[j].id === keptId) {
|
|
17
|
-
startIndex = j;
|
|
18
|
-
break;
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
} else {
|
|
22
|
-
startIndex = i + 1;
|
|
23
|
-
}
|
|
24
|
-
break;
|
|
25
|
-
}
|
|
7
|
+
export function estimateEntryTokens(entry: { type: string; message?: unknown; content?: unknown; summary?: unknown }): number {
|
|
8
|
+
if (entry.type === "message" && entry.message) {
|
|
9
|
+
return estimateMessageTokens(entry.message as Parameters<typeof estimateMessageTokens>[0]);
|
|
26
10
|
}
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
const content = entry.content;
|
|
35
|
-
if (typeof content === "string") {
|
|
36
|
-
tokens += Math.ceil(content.length / 4);
|
|
37
|
-
} else if (Array.isArray(content)) {
|
|
38
|
-
for (const block of content) {
|
|
39
|
-
if (block.type === "text" && block.text) tokens += Math.ceil(block.text.length / 4);
|
|
40
|
-
}
|
|
11
|
+
if (entry.type === "custom_message" && entry.content) {
|
|
12
|
+
const content = entry.content;
|
|
13
|
+
if (typeof content === "string") return estimateStringTokens(content);
|
|
14
|
+
if (Array.isArray(content)) {
|
|
15
|
+
let total = 0;
|
|
16
|
+
for (const block of content) {
|
|
17
|
+
if (block.type === "text" && block.text) total += estimateStringTokens(block.text);
|
|
41
18
|
}
|
|
19
|
+
return total;
|
|
42
20
|
}
|
|
43
21
|
}
|
|
44
|
-
|
|
22
|
+
if (entry.type === "branch_summary" && typeof entry.summary === "string") {
|
|
23
|
+
return estimateStringTokens(entry.summary);
|
|
24
|
+
}
|
|
25
|
+
return 0;
|
|
45
26
|
}
|
|
46
27
|
|
|
47
|
-
export function extractText(response: { content: Array<{ type: string; text?: string }> }): string {
|
|
48
|
-
return response.content
|
|
49
|
-
.filter((c): c is { type: "text"; text: string } => c.type === "text")
|
|
50
|
-
.map((c) => c.text)
|
|
51
|
-
.join("\n");
|
|
52
|
-
}
|
package/src/types.ts
CHANGED
|
@@ -1,15 +1,64 @@
|
|
|
1
|
-
export
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
export const OBSERVATION_CUSTOM_TYPE = "om.observation";
|
|
2
|
+
|
|
3
|
+
export type Relevance = "low" | "medium" | "high" | "critical";
|
|
4
|
+
|
|
5
|
+
export const RELEVANCE_VALUES: readonly Relevance[] = ["low", "medium", "high", "critical"] as const;
|
|
6
|
+
|
|
7
|
+
export interface ObservationRecord {
|
|
8
|
+
id: string;
|
|
9
|
+
content: string;
|
|
10
|
+
timestamp: string;
|
|
11
|
+
relevance: Relevance;
|
|
4
12
|
}
|
|
5
13
|
|
|
14
|
+
export type Reflection = string;
|
|
15
|
+
|
|
6
16
|
export interface MemoryDetails {
|
|
7
17
|
type: "observational-memory";
|
|
8
|
-
version:
|
|
9
|
-
observations:
|
|
10
|
-
reflections:
|
|
18
|
+
version: 3;
|
|
19
|
+
observations: ObservationRecord[];
|
|
20
|
+
reflections: Reflection[];
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export interface ObservationEntryData {
|
|
24
|
+
records: ObservationRecord[];
|
|
25
|
+
coversFromId: string;
|
|
26
|
+
coversUpToId: string;
|
|
27
|
+
tokenCount: number;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function isRelevance(v: unknown): v is Relevance {
|
|
31
|
+
return typeof v === "string" && (RELEVANCE_VALUES as readonly string[]).includes(v);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function isObservationRecord(v: unknown): v is ObservationRecord {
|
|
35
|
+
if (!v || typeof v !== "object") return false;
|
|
36
|
+
const o = v as Record<string, unknown>;
|
|
37
|
+
return (
|
|
38
|
+
typeof o.id === "string" &&
|
|
39
|
+
typeof o.content === "string" &&
|
|
40
|
+
typeof o.timestamp === "string" &&
|
|
41
|
+
isRelevance(o.relevance)
|
|
42
|
+
);
|
|
11
43
|
}
|
|
12
44
|
|
|
13
45
|
export function isMemoryDetails(d: unknown): d is MemoryDetails {
|
|
14
|
-
|
|
46
|
+
if (!d || typeof d !== "object") return false;
|
|
47
|
+
const o = d as Record<string, unknown>;
|
|
48
|
+
if (o.type !== "observational-memory" || o.version !== 3) return false;
|
|
49
|
+
if (!Array.isArray(o.observations) || !Array.isArray(o.reflections)) return false;
|
|
50
|
+
if (!o.observations.every(isObservationRecord)) return false;
|
|
51
|
+
return o.reflections.every((r) => typeof r === "string");
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export function isObservationEntryData(d: unknown): d is ObservationEntryData {
|
|
55
|
+
if (!d || typeof d !== "object") return false;
|
|
56
|
+
const o = d as Record<string, unknown>;
|
|
57
|
+
return (
|
|
58
|
+
Array.isArray(o.records) &&
|
|
59
|
+
o.records.every(isObservationRecord) &&
|
|
60
|
+
typeof o.coversFromId === "string" &&
|
|
61
|
+
typeof o.coversUpToId === "string" &&
|
|
62
|
+
typeof o.tokenCount === "number"
|
|
63
|
+
);
|
|
15
64
|
}
|