-
Notifications
You must be signed in to change notification settings - Fork 31
feat(core): implement parseMemory with structured section extraction #747
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,6 +1,61 @@ | ||
| export function parseMemory(markdown: string): Record<string, any> { | ||
| // TODO: Parse memory markdown into structured data | ||
| return { raw: markdown }; | ||
| export interface ParsedMemory { | ||
| /** Content under the "## User Profile" section. */ | ||
| userProfile: string; | ||
| /** Content under the "## Key Facts" section. */ | ||
| keyFacts: string; | ||
| /** Content under the "## Ongoing Context" section. */ | ||
| ongoingContext: string; | ||
| /** Content between MANUAL:START and MANUAL:END markers. */ | ||
| manualNotes: string; | ||
| /** The full raw markdown input, preserved for round-tripping. */ | ||
| raw: string; | ||
| } | ||
|
|
||
| /** | ||
| * Parse a Signet memory markdown file into structured sections. | ||
| * | ||
| * Extracts content from well-known `## ` headings and the | ||
| * `<!-- MANUAL:START -->` / `<!-- MANUAL:END -->` block. Any content | ||
| * outside recognized sections is ignored — the `raw` field always | ||
| * contains the original markdown for lossless round-tripping. | ||
| */ | ||
| export function parseMemory(markdown: string): ParsedMemory { | ||
| const sections: Record<string, string> = {}; | ||
| let currentSection: string | null = null; | ||
| const sectionLines: string[] = []; | ||
|
|
||
| const lines = markdown.split("\n"); | ||
| for (const line of lines) { | ||
| const headingMatch = line.match(/^##\s+(.+)/); | ||
| if (headingMatch) { | ||
| // Flush previous section | ||
| if (currentSection !== null) { | ||
| sections[currentSection] = sectionLines.join("\n").trim(); | ||
| } | ||
| currentSection = headingMatch[1].trim(); | ||
| sectionLines.length = 0; | ||
| } else if (currentSection !== null) { | ||
| sectionLines.push(line); | ||
| } | ||
| } | ||
| // Flush last section | ||
| if (currentSection !== null) { | ||
| sections[currentSection] = sectionLines.join("\n").trim(); | ||
| } | ||
|
|
||
| // Extract manual notes block | ||
| const manualMatch = markdown.match( | ||
| /<!--\s*MANUAL:START\s*-->([\s\S]*?)<!--\s*MANUAL:END\s*-->/, | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The parser returns the generated placeholder text ( |
||
| ); | ||
| const manualNotes = manualMatch ? manualMatch[1].trim() : ""; | ||
|
|
||
| return { | ||
| userProfile: sections["User Profile"] ?? "", | ||
| keyFacts: sections["Key Facts"] ?? "", | ||
| ongoingContext: sections["Ongoing Context"] ?? "", | ||
| manualNotes, | ||
| raw: markdown, | ||
| }; | ||
| } | ||
|
|
||
| export function generateMemory(): string { | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This keeps collecting lines after
## Ongoing Contextuntil another##heading appears, butgenerateMemory()puts the<!-- MANUAL:START --> ... <!-- MANUAL:END -->block after Ongoing Context without a new heading. As a result,parseMemory(generateMemory()).ongoingContextincludes the manual-marker comments, whilemanualNotesseparately extracts the placeholder comment. That diverges from the PR's claim that the generated template parses into empty fields and gives consumers polluted section content.