fix: broadcast uses summaryForStore to support salvaged summaries (#1718)
syncAndBroadcastSummary was using the raw ParsedSummary (null when salvaged) instead of summaryForStore for the SSE broadcast, causing a crash when the LLM returns <observation> without <summary> tags. Also removes misplaced tree-sitter docs from mem-search/SKILL.md (belongs in smart-explore). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
File diff suppressed because one or more lines are too long
+234
-232
File diff suppressed because one or more lines are too long
@@ -126,54 +126,6 @@ get_observations(ids=[11131, 10942, 10855], orderBy="date_desc")
|
|||||||
- **Batch fetch:** 1 HTTP request vs N individual requests
|
- **Batch fetch:** 1 HTTP request vs N individual requests
|
||||||
- **10x token savings** by filtering before fetching
|
- **10x token savings** by filtering before fetching
|
||||||
|
|
||||||
## Smart-Explore Language Support
|
|
||||||
|
|
||||||
Smart-explore tools (`smart_search`, `smart_outline`, `smart_unfold`) use tree-sitter AST parsing. The following languages are supported out of the box.
|
|
||||||
|
|
||||||
### 24 Bundled Languages
|
|
||||||
|
|
||||||
JS, TS, Python, Go, Rust, Ruby, Java, C, C++, Kotlin, Swift, PHP, Elixir, Lua, Scala, Bash, Haskell, Zig, CSS, SCSS, TOML, YAML, SQL, Markdown
|
|
||||||
|
|
||||||
### Markdown Special Support
|
|
||||||
|
|
||||||
Markdown files get structure-aware parsing beyond generic tree-sitter:
|
|
||||||
|
|
||||||
- **Heading hierarchy** -- `#`/`##`/`###` headings are extracted as nested symbols (sections contain subsections)
|
|
||||||
- **Code block detection** -- fenced code blocks are surfaced as `code` symbols with language annotation
|
|
||||||
- **Section-aware unfold** -- `smart_unfold` on a heading returns the full section content (heading through all subsections until the next heading of equal or higher level)
|
|
||||||
|
|
||||||
### User-Installable Grammars via `.claude-mem.json`
|
|
||||||
|
|
||||||
Add custom tree-sitter grammars for languages not in the bundled set. Place `.claude-mem.json` in the project root:
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"grammars": {
|
|
||||||
"gleam": {
|
|
||||||
"package": "tree-sitter-gleam",
|
|
||||||
"extensions": [".gleam"]
|
|
||||||
},
|
|
||||||
"protobuf": {
|
|
||||||
"package": "tree-sitter-proto",
|
|
||||||
"extensions": [".proto"],
|
|
||||||
"query": ".claude-mem/queries/proto.scm"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
**Fields:**
|
|
||||||
|
|
||||||
- `package` (string, required) -- npm package name for the tree-sitter grammar
|
|
||||||
- `extensions` (array of strings, required) -- file extensions to associate with this language
|
|
||||||
- `query` (string, optional) -- path to a custom `.scm` query file for symbol extraction. If omitted, a generic query is used.
|
|
||||||
|
|
||||||
**Rules:**
|
|
||||||
|
|
||||||
- User grammars do NOT override bundled languages. If a language is already bundled, the entry is ignored.
|
|
||||||
- The npm package must be installed in the project (`npm install tree-sitter-gleam`).
|
|
||||||
- Config is cached per project root. Changes to `.claude-mem.json` take effect on next worker restart.
|
|
||||||
|
|
||||||
## Knowledge Agents
|
## Knowledge Agents
|
||||||
|
|
||||||
Want synthesized answers instead of raw records? Use `/knowledge-agent` to build a queryable corpus from your observation history. The knowledge agent reads all matching observations and answers questions conversationally.
|
Want synthesized answers instead of raw records? Use `/knowledge-agent` to build a queryable corpus from your observation history. The knowledge agent reads all matching observations and answers questions conversationally.
|
||||||
|
|||||||
+11
-11
File diff suppressed because one or more lines are too long
@@ -354,12 +354,12 @@ async function syncAndBroadcastSummary(
|
|||||||
id: result.summaryId,
|
id: result.summaryId,
|
||||||
session_id: session.contentSessionId,
|
session_id: session.contentSessionId,
|
||||||
platform_source: session.platformSource,
|
platform_source: session.platformSource,
|
||||||
request: summary!.request,
|
request: summaryForStore!.request,
|
||||||
investigated: summary!.investigated,
|
investigated: summaryForStore!.investigated,
|
||||||
learned: summary!.learned,
|
learned: summaryForStore!.learned,
|
||||||
completed: summary!.completed,
|
completed: summaryForStore!.completed,
|
||||||
next_steps: summary!.next_steps,
|
next_steps: summaryForStore!.next_steps,
|
||||||
notes: summary!.notes,
|
notes: summaryForStore!.notes,
|
||||||
project: session.project,
|
project: session.project,
|
||||||
prompt_number: session.lastPromptNumber,
|
prompt_number: session.lastPromptNumber,
|
||||||
created_at_epoch: result.createdAtEpoch
|
created_at_epoch: result.createdAtEpoch
|
||||||
|
|||||||
@@ -319,7 +319,9 @@ describe('ResponseProcessor', () => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
const [, , , summary] = mockStoreObservations.mock.calls[0];
|
const [, , , summary] = mockStoreObservations.mock.calls[0];
|
||||||
expect(summary).toBeNull();
|
// #1718: When observations exist without <summary> tags, a synthetic summary is salvaged
|
||||||
|
expect(summary).not.toBeNull();
|
||||||
|
expect(summary.notes).toContain('Salvaged from');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user