1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
//! The three daemon calls `prompt-context` makes (#6286).
//!
//! Why: isolates the network hops — global hot facts, per-palace recall,
//! per-palace KG triples — so each can be read and extended without touching
//! the orchestration in `mod.rs`.
//!
//! What changed with ADR-0032: these were three `GET`s against
//! `/api/v1/kg/prompt-context`, `…/recall` and `…/kg/all`, built from a
//! `reqwest::Client` and a base URL read out of the `http_addr` discovery file.
//! They are now three [`crate::client::call_at`] frames against the daemon's
//! socket. Two of the three were already tool names the dispatcher routed —
//! `get_prompt_context` and `memory_recall` — so the REST routes were
//! duplicates; the third is the folded `memory.kg_all`.
//!
//! **Every one still degrades to empty on any failure.** This runs inside
//! Claude Code's `UserPromptSubmit` hook, so a degraded or absent daemon must
//! cost the user nothing but the missing context. That is why each helper
//! swallows its error rather than propagating it, and why the caller passes a
//! sub-second budget.
//!
//! Test: `prompt_context_recalls_palace_drawers`,
//! `prompt_context_empty_palace_falls_back_to_global`.
use Path;
use Duration;
use ;
use ;
use EMPTY_PLACEHOLDER;
/// How many triples to pull before filtering them in memory.
///
/// The filter is a substring scan over subjects, so 200 keeps it cheap while
/// covering any palace whose ambient facts are worth injecting at all.
const KG_TRIPLE_LIMIT: u64 = 200;
/// Fetch the global prompt-context block (workspace hot facts).
///
/// Why: keeps workspace-level aliases and conventions surfacing even when the
/// palace itself is empty.
/// What: calls `get_prompt_context`; returns `Some` only for a non-empty,
/// non-placeholder body. Any failure is `None`.
/// Test: `prompt_context_recalls_palace_drawers`,
/// `prompt_context_empty_palace_falls_back_to_global`.
pub async
/// Fetch up to `top_k` recalled drawers from the palace.
///
/// Why (#134): surfacing relevant memories is the whole value of automatic
/// context injection.
/// What: calls `memory_recall`, which answers `{palace, query, results: [...]}`
/// — the REST route this replaces returned the bare array, so the entries are
/// read out of `results` here. An empty prompt, a refusal, or an unreachable
/// daemon all yield an empty vec.
/// Test: `prompt_context_recalls_palace_drawers`.
pub async
/// Fetch active KG triples from the palace.
///
/// Why (#134): subject-anchored triples — `tga is_alias_for
/// trusty-git-analytics`, `rust is-a language` — are exactly the ambient facts
/// a model benefits from when the prompt names one of those subjects.
/// What: calls the folded `memory.kg_all` with a [`KG_TRIPLE_LIMIT`] page;
/// returns the raw triples, empty on any failure.
/// Test: `prompt_context_recalls_palace_drawers`.
pub async