Skip to content

Commit cd86c0e

Browse files
author
SqlRush
committed
Accept memory fact kind aliases
1 parent 9cf6a6c commit cd86c0e

4 files changed

Lines changed: 41 additions & 4 deletions

File tree

docs/cc-100-roadmap.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -544,6 +544,8 @@ M7 补充:prompt history `LogEntry` 读取现在接受 `sessionID`/`session`/`
544544

545545
本轮补充:model-backed memory fact extraction 现在会穿透 `observations`/`notes`/`findings`/`records``data.resource.attributes``edge.node` 这类 API 包装集合,并接受 `note`/`description`/`body`/`message`/`observation`/`finding` 作为 fact 正文字段别名。
546546

547+
本轮补充:model-backed memory fact extraction 现在接受更多 kind aliases,包括 `user_pref``requirement``action_item``outcome``conclusion``tool_usage``command_run`,并归一到 preference/request/decision/tool。
548+
547549
本轮补充:compact runner 的 summary 响应现在也接受 provider-style `choices`/`outputs`/`candidates`/`generations` wrapper,可在构建 compact plan 前从 `message.content`、content-block array、`content.parts[].text` 和 fenced `json` code block 中恢复 visible summary text。
548550

549551
本轮补充:remote history response parser 现在也接受 provider-style `choices`/`outputs`/`candidates`/`generations` wrapper 以及顶层 `message`/`content`/`text` envelope,可从 `message.content`、content-block array 和 `content.parts[].text` 中恢复 event page JSON(包括 fenced `json` code block),并保留 pagination 继续驱动 `before_id` 续抓。

docs/first-second-parity-audit.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,7 @@ M6 progress now includes:
154154
- `internal/memory`: session-memory recall and relevant-memory model selectors now also accept HAL/JSON:API-style `links` and `_links` relation objects, extracting `href`/`url`/`uri`/`link` paths while ignoring relation metadata.
155155
- `internal/memory`: model-backed memory fact extraction now also unwraps provider-style `choices`, `outputs`, `candidates`, and `generations` responses plus top-level `message`/`content`/`text`/`output_text` envelopes, recovering JSON facts payloads from nested `message.content`, content-block arrays, `content.parts[].text`, and fenced `json` code blocks.
156156
- `internal/memory`: model-backed memory fact extraction now also traverses API-shaped fact collections such as `observations`, `notes`, `findings`, `records`, `resources`, `data.resource.attributes`, and `edge.node`, while accepting text aliases such as `note`, `description`, `body`, `message`, `observation`, and `finding`.
157+
- `internal/memory`: model-backed memory fact extraction now accepts additional kind aliases such as `user_pref`, `requirement`, `action_item`, `outcome`, `conclusion`, `tool_usage`, and `command_run`, normalizing them into preference/request/decision/tool facts.
157158
- `internal/session`: remote-history response parsing now also unwraps provider-style `choices`, `outputs`, `candidates`, and `generations` responses plus top-level `message`/`content`/`text`/`output_text` envelopes, recovering event page JSON plus pagination from nested `message.content`, content-block arrays, `content.parts[].text`, and fenced `json` code blocks.
158159
- `internal/session`: remote-history pagination now accepts `starting_after`/`startingAfter`/`after*` cursor aliases from page fields and link URL query parameters when deriving the next `before_id`.
159160
- `internal/session`: project session listing and pagination, prompt-history lock/buffered flush/field aliases, lightweight transcript index/title/text-preview inference, line-offset transcript indexing/window/byte-budget-window/parent-chain/resume/tail/byte-budget-tail loading, AI-title/last-prompt/task/agent/PR/worktree transcript metadata loading and type/field aliases, transcript message/session UUID field aliases, tombstone metadata loading with target/session/reason aliases and delete/relink replay, agent-scoped content replacement metadata/record field-alias loading, session-scoped metadata reappend including AI-title/last-prompt/task-summary, streaming transcript search snippets for resume/search UI, official `subagents/agent-*.jsonl` transcript layout with legacy sidechain listing, agent metadata sidecar read/write/field aliases, sidechain runtime start/append/finish/cancel/fail summary bridging plus parent-chain append/finish, sidechain manager orchestration for spawn/append/finish/cancel/fail/list/resume, sidechain state/list/resume support with content-field aliases, sidechain resume context construction, sidechain conversation and agent-scoped content-replacement reconstruction, transcript tail/window loading and byte-budget tail loading for bounded-memory resume/UI paths, lightweight transcript metadata loading, remote-history token refresh retry, page-field/event-list/records/entries/last-id/cursor/event-id/has-next aliases plus wrapped-data/links/paging/bare-array/keyed-event-map responses, before_id resume, fallback field fill, and duplicate-aware parent linking during transcript materialization.

internal/memory/agent.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2309,13 +2309,13 @@ func normalizeFactKind(raw string) (FactKind, bool) {
23092309
name := strings.ToLower(strings.TrimSpace(raw))
23102310
name = strings.NewReplacer("-", "_", " ", "_").Replace(name)
23112311
switch name {
2312-
case "preference", "pref", "user_preference", "memory_preference":
2312+
case "preference", "pref", "user_pref", "user_preference", "memory_preference", "personal_preference", "instruction", "user_instruction":
23132313
return FactPreference, true
2314-
case "request", "user_request", "ask", "todo", "task":
2314+
case "request", "user_request", "ask", "todo", "task", "requirement", "user_requirement", "action_item", "follow_up", "followup":
23152315
return FactRequest, true
2316-
case "decision", "decided", "choice", "resolution":
2316+
case "decision", "decided", "choice", "resolution", "outcome", "conclusion", "agreement":
23172317
return FactDecision, true
2318-
case "tool", "tool_use", "tool_result", "tool_call":
2318+
case "tool", "tool_use", "tool_usage", "tool_result", "tool_call", "command", "command_run", "operation":
23192319
return FactTool, true
23202320
default:
23212321
return "", false

internal/memory/memory_test.go

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1211,6 +1211,40 @@ func TestMemoryAgentExtractsFactKindAliases(t *testing.T) {
12111211
}
12121212
}
12131213

1214+
func TestMemoryAgentExtractsAdditionalFactKindAliases(t *testing.T) {
1215+
client := &fakeMemoryClient{response: &anthropic.Response{
1216+
ID: "msg_memory_kind_aliases_more",
1217+
Type: "message",
1218+
Role: "assistant",
1219+
Model: "sonnet",
1220+
Content: []contracts.ContentBlock{contracts.NewTextBlock(`{"facts":[
1221+
{"kind":"user_pref","text":"prefer alias coverage","source_uuid":"user_1"},
1222+
{"type":"requirement","content":"continue M6 fact parsing","source_id":"user_2"},
1223+
{"category":"outcome","summary":"keep model facts ordered","uuid":"assistant_1"},
1224+
{"label":"tool_usage","detail":"Used tool RG","messageUuid":"assistant_2"}
1225+
]}`)},
1226+
}}
1227+
result, err := (Agent{Client: client}).Extract(context.Background(), []contracts.Message{msgs.UserText("Remember aliases")}, ExtractOptions{})
1228+
if err != nil {
1229+
t.Fatal(err)
1230+
}
1231+
if result.Fallback || len(result.Facts) != 4 {
1232+
t.Fatalf("result = %#v", result)
1233+
}
1234+
if !hasMemoryFact(result.Facts, FactPreference, "prefer alias coverage", "user_1") {
1235+
t.Fatalf("preference alias missing = %#v", result.Facts)
1236+
}
1237+
if !hasMemoryFact(result.Facts, FactRequest, "continue M6 fact parsing", "user_2") {
1238+
t.Fatalf("request alias missing = %#v", result.Facts)
1239+
}
1240+
if !hasMemoryFact(result.Facts, FactDecision, "keep model facts ordered", "assistant_1") {
1241+
t.Fatalf("decision alias missing = %#v", result.Facts)
1242+
}
1243+
if !hasMemoryFact(result.Facts, FactTool, "Used tool RG", "assistant_2") {
1244+
t.Fatalf("tool alias missing = %#v", result.Facts)
1245+
}
1246+
}
1247+
12141248
func TestMemoryAgentExtractsNestedFactResponseShapes(t *testing.T) {
12151249
client := &fakeMemoryClient{response: &anthropic.Response{
12161250
ID: "msg_memory_nested_fields",

0 commit comments

Comments
 (0)