claude-recall 0.32.0 → 0.33.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 +6 -4
- package/dist/hooks/llm-classifier.js +11 -10
- package/dist/hooks/shared.js +24 -30
- package/docs/cc-llm-capture.md +147 -0
- package/docs/kiro-llm-capture.md +15 -11
- package/docs/kiro.md +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -92,6 +92,8 @@ tail -5 ~/.claude-recall/hook-logs/cc-classifier.log # which model ran, what w
|
|
|
92
92
|
claude-recall search "something you said"
|
|
93
93
|
```
|
|
94
94
|
|
|
95
|
+
Design details (the `claude -p` key-precedence gotcha, recursion guards, which features run on the subscription): [docs/cc-llm-capture.md](docs/cc-llm-capture.md).
|
|
96
|
+
|
|
95
97
|
### Pi
|
|
96
98
|
|
|
97
99
|
```bash
|
|
@@ -169,7 +171,7 @@ Once installed, Claude Recall works in the background (CC = Claude Code):
|
|
|
169
171
|
| **Session exit** | An auto-checkpoint (`{completed, remaining, blockers}`) is saved for next time | ✓ | ✓ | |
|
|
170
172
|
| **End of session** | Failure patterns become candidate lessons; validated ones are promoted to rules | ✓ | ✓ | |
|
|
171
173
|
|
|
172
|
-
Classification runs on each runtime's **own** LLM — Claude Code via headless `claude -p` on your subscription; Kiro via `kiro-cli chat --no-interactive` on Kiro credits — with `ANTHROPIC_API_KEY`
|
|
174
|
+
Classification runs on each runtime's **own** LLM — Claude Code via headless `claude -p` on your subscription; Kiro via `kiro-cli chat --no-interactive` on Kiro credits — with regex as the fallback. **An exported `ANTHROPIC_API_KEY` is never touched** unless you explicitly opt in with `CLAUDE_RECALL_PREFER_API_KEY=1`. No API key is ever required; no configuration needed.
|
|
173
175
|
|
|
174
176
|
```bash
|
|
175
177
|
# Verify it's working
|
|
@@ -206,7 +208,7 @@ claude-recall checkpoint save --completed "API layer" --remaining "wire the UI"
|
|
|
206
208
|
claude-recall checkpoint load
|
|
207
209
|
```
|
|
208
210
|
|
|
209
|
-
Auto-checkpoints are also saved on session exit in Claude Code and Pi (Pi has no `--resume`, so this is its main recovery path). Extraction runs on your **Claude subscription** (headless `claude -p`) — like capture, no API key needed
|
|
211
|
+
Auto-checkpoints are also saved on session exit in Claude Code and Pi (Pi has no `--resume`, so this is its main recovery path). Extraction runs on your **Claude subscription** (headless `claude -p`) — like capture, no API key needed and no key touched. The same applies to the other background LLM features (failure hindsight hints, end-of-session lesson extraction). Pi-only machines without the `claude` binary can opt in to an `ANTHROPIC_API_KEY` with `CLAUDE_RECALL_PREFER_API_KEY=1`. A quality gate refuses to overwrite a manual checkpoint with a fabricated one when the task was already complete.
|
|
210
212
|
|
|
211
213
|
### Troubleshooting
|
|
212
214
|
|
|
@@ -387,11 +389,11 @@ Defaults work out of the box; tune via environment variables as needed.
|
|
|
387
389
|
| Variable | Default | Effect |
|
|
388
390
|
| ---------------------------------------- | ------- | -------------------------------------------------------------------------------------------------------- |
|
|
389
391
|
| `CLAUDE_RECALL_DB_PATH` | `~/.claude-recall/` | Database directory. |
|
|
390
|
-
| `ANTHROPIC_API_KEY` | _(unset)_ | Optional personal API key for Haiku-based LLM features. **Never required
|
|
392
|
+
| `ANTHROPIC_API_KEY` | _(unset)_ | Optional personal API key for Haiku-based LLM features. **Never required, never provided by Claude Code, and never touched unless you opt in** with `CLAUDE_RECALL_PREFER_API_KEY=1` — capture, checkpoint extraction, hindsight hints, and session lessons all run on each runtime's own LLM (Claude subscription via `claude -p`; Kiro credits via `kiro-cli`), with regex as the fallback. |
|
|
391
393
|
| `CLAUDE_RECALL_CC_MODEL` | `haiku` | Dedicated model for capture classification under Claude Code (passed to `claude -p --model`) — independent of your interactive session model. |
|
|
392
394
|
| `CLAUDE_RECALL_CC_LLM_TIMEOUT_MS` | `30000` | Hard cap on the headless `claude -p` classify call before the capture worker gives up and falls through. |
|
|
393
395
|
| `CLAUDE_RECALL_KIRO_MODEL` | `claude-haiku-4.5` | Dedicated model for Kiro-LLM capture classification — **independent of your interactive Kiro chat model**. Raise to `claude-sonnet-4.6` for steadier judgement at more credits. See [docs/kiro-llm-capture.md](docs/kiro-llm-capture.md). |
|
|
394
|
-
| `CLAUDE_RECALL_PREFER_API_KEY` | _(unset)_ |
|
|
396
|
+
| `CLAUDE_RECALL_PREFER_API_KEY` | _(unset)_ | **The only switch that enables the `ANTHROPIC_API_KEY` backend** (and prefers it first). For Pi-only machines without the `claude` binary, or a stronger model you deliberately pay for. Applies to all LLM features, under Claude Code, Kiro, and Pi. |
|
|
395
397
|
| `CLAUDE_RECALL_KIRO_LLM_TIMEOUT_MS` | `30000` | Hard cap on the headless `kiro-cli` classify call before the capture worker gives up and falls back to regex. |
|
|
396
398
|
| `CLAUDE_RECALL_LOAD_BUDGET_TOKENS` | `2000` | Token budget for the `load_rules` payload. Rules are emitted in priority order (corrections → preferences by citation → devops by citation → failures) and dropped rules surface via `search_memory`. |
|
|
397
399
|
| `CLAUDE_RECALL_AUTO_DEMOTE` | `false` | When `true`, auto-demote rules on MCP boot where `load_count >= CLAUDE_RECALL_DEMOTE_MIN_LOADS`, `cite_count = 0`, and age `> CLAUDE_RECALL_DEMOTE_MIN_AGE_DAYS`. Still reversible via `rules promote <id>`. |
|
|
@@ -5,10 +5,10 @@
|
|
|
5
5
|
* Requires ANTHROPIC_API_KEY in the environment — a personal pay-as-you-go
|
|
6
6
|
* API key the user exported themselves. Claude Code does NOT mint one from
|
|
7
7
|
* the user's subscription (hooks just inherit the user's environment), which
|
|
8
|
-
* is why this is
|
|
9
|
-
* runtime's included LLM (claude -p / kiro-cli —
|
|
10
|
-
* kiro-classifier.ts) and
|
|
11
|
-
* gracefully (returns null) when unavailable.
|
|
8
|
+
* is why this backend is STRICTLY OPT-IN (CLAUDE_RECALL_PREFER_API_KEY): the
|
|
9
|
+
* default chains use each runtime's included LLM only (claude -p / kiro-cli —
|
|
10
|
+
* see cc-classifier.ts and kiro-classifier.ts), and an exported key is never
|
|
11
|
+
* spent silently. Falls back gracefully (returns null) when unavailable.
|
|
12
12
|
*/
|
|
13
13
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
14
|
exports.classifyWithLLM = classifyWithLLM;
|
|
@@ -146,11 +146,12 @@ function parseJSON(text) {
|
|
|
146
146
|
* extraction, checkpoint extraction, batch classification) and return raw
|
|
147
147
|
* text, or null when no backend is available.
|
|
148
148
|
*
|
|
149
|
-
* Backend
|
|
150
|
-
* `claude -p`)
|
|
151
|
-
*
|
|
152
|
-
* never
|
|
153
|
-
*
|
|
149
|
+
* Backend policy matches capture: the user's Claude SUBSCRIPTION (headless
|
|
150
|
+
* `claude -p`) is the only default backend — a personally-exported
|
|
151
|
+
* ANTHROPIC_API_KEY is STRICTLY OPT-IN via CLAUDE_RECALL_PREFER_API_KEY and
|
|
152
|
+
* never consulted otherwise, not even as a fallback. The opt-in exists for
|
|
153
|
+
* Pi-only users (no `claude` binary; their key is how they run Pi itself)
|
|
154
|
+
* and anyone deliberately paying for a stronger model.
|
|
154
155
|
*
|
|
155
156
|
* The CLI backend is skipped inside a nested headless session
|
|
156
157
|
* (CLAUDE_RECALL_NESTED): if `claude -p` fires user-scope hooks of its own,
|
|
@@ -182,7 +183,7 @@ async function completeText(systemPrompt, userContent, maxTokens) {
|
|
|
182
183
|
: (0, cc_classifier_1.completeWithClaudeCli)(`${systemPrompt}\n\n${userContent}`, { timeoutMs: SECONDARY_CLI_TIMEOUT_MS });
|
|
183
184
|
const backends = process.env.CLAUDE_RECALL_PREFER_API_KEY
|
|
184
185
|
? [viaApi, viaCli]
|
|
185
|
-
: [viaCli
|
|
186
|
+
: [viaCli];
|
|
186
187
|
for (const backend of backends) {
|
|
187
188
|
const text = await backend();
|
|
188
189
|
if (text !== null && text.trim().length > 0)
|
package/dist/hooks/shared.js
CHANGED
|
@@ -166,18 +166,17 @@ function classifyContentRegex(text) {
|
|
|
166
166
|
* workers, which set the *_CLASSIFIER env vars — a ~4s CLI call can't run
|
|
167
167
|
* inline on a turn):
|
|
168
168
|
* - Under Claude Code (CLAUDE_RECALL_CC_CLASSIFIER set by cc-capture-worker):
|
|
169
|
-
* headless `claude -p` on the user's Claude SUBSCRIPTION →
|
|
170
|
-
* if present → regex.
|
|
169
|
+
* headless `claude -p` on the user's Claude SUBSCRIPTION → regex.
|
|
171
170
|
* - Under Kiro (CLAUDE_RECALL_KIRO_CLASSIFIER set by kiro-capture-worker):
|
|
172
171
|
* Kiro's own headless LLM (`kiro-cli chat --no-interactive`, Kiro credits)
|
|
173
|
-
* →
|
|
174
|
-
* - Inline callers
|
|
172
|
+
* → regex.
|
|
173
|
+
* - Inline callers: straight to regex.
|
|
175
174
|
*
|
|
176
|
-
* The
|
|
177
|
-
*
|
|
178
|
-
*
|
|
179
|
-
* exported — Claude Code does NOT provide one from the subscription.
|
|
180
|
-
* See docs/kiro-llm-capture.md.
|
|
175
|
+
* The ANTHROPIC_API_KEY path is STRICTLY OPT-IN via
|
|
176
|
+
* CLAUDE_RECALL_PREFER_API_KEY — an exported key is never consulted
|
|
177
|
+
* otherwise, not even as a fallback. (It is always a personal key the user
|
|
178
|
+
* exported — Claude Code does NOT provide one from the subscription.)
|
|
179
|
+
* See docs/cc-llm-capture.md and docs/kiro-llm-capture.md.
|
|
181
180
|
*/
|
|
182
181
|
async function classifyContent(text) {
|
|
183
182
|
// Guard the LLM paths the same way the regex path is guarded: a question or
|
|
@@ -202,30 +201,25 @@ async function classifyContentInner(text) {
|
|
|
202
201
|
// module graph for hook invocations that don't run in a capture worker.
|
|
203
202
|
const tryKiro = async () => (await Promise.resolve().then(() => __importStar(require('./kiro-classifier')))).classifyWithKiro(text);
|
|
204
203
|
const tryCc = async () => (await Promise.resolve().then(() => __importStar(require('./cc-classifier')))).classifyWithClaudeCli(text);
|
|
205
|
-
//
|
|
206
|
-
//
|
|
207
|
-
//
|
|
208
|
-
//
|
|
209
|
-
//
|
|
210
|
-
//
|
|
211
|
-
//
|
|
212
|
-
//
|
|
213
|
-
//
|
|
204
|
+
// Pick the LLM backends. The ANTHROPIC_API_KEY path is STRICTLY OPT-IN
|
|
205
|
+
// (CLAUDE_RECALL_PREFER_API_KEY): claude-recall was built for runtimes that
|
|
206
|
+
// bring their own LLM — Kiro via `kiro-cli chat --no-interactive` (Kiro
|
|
207
|
+
// credits), Claude Code via `claude -p` (the user's Claude subscription) —
|
|
208
|
+
// and a key exported for other tools must NEVER be spent silently, not even
|
|
209
|
+
// as a fallback. Without the opt-in, the chain is included LLM → regex.
|
|
210
|
+
// The opt-in exists for Pi-only users (no `claude` binary; their key is how
|
|
211
|
+
// they run Pi itself) and anyone deliberately paying for a stronger model.
|
|
212
|
+
// The CLI backends only run inside their detached capture workers (which
|
|
213
|
+
// set the *_CLASSIFIER env vars) — inline hook paths go straight to regex,
|
|
214
|
+
// since a ~4s CLI call can't block a turn.
|
|
214
215
|
const backends = [];
|
|
215
|
-
if (
|
|
216
|
-
backends.push(
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
backends.push(tryApiKey, tryKiro);
|
|
220
|
-
}
|
|
221
|
-
else if (underCc && !preferApiKey) {
|
|
222
|
-
backends.push(tryCc, tryApiKey);
|
|
216
|
+
if (preferApiKey)
|
|
217
|
+
backends.push(tryApiKey);
|
|
218
|
+
if (underKiro) {
|
|
219
|
+
backends.push(tryKiro);
|
|
223
220
|
}
|
|
224
221
|
else if (underCc) {
|
|
225
|
-
backends.push(
|
|
226
|
-
}
|
|
227
|
-
else {
|
|
228
|
-
backends.push(tryApiKey);
|
|
222
|
+
backends.push(tryCc);
|
|
229
223
|
}
|
|
230
224
|
for (const backend of backends) {
|
|
231
225
|
const result = await backend();
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
# Using your Claude subscription for memory capture (no API key)
|
|
2
|
+
|
|
3
|
+
The Claude Code counterpart to [kiro-llm-capture.md](kiro-llm-capture.md): how
|
|
4
|
+
claude-recall's LLM features run on the user's **Claude subscription** — the
|
|
5
|
+
same login that powers their interactive session — instead of a personal
|
|
6
|
+
`ANTHROPIC_API_KEY`.
|
|
7
|
+
|
|
8
|
+
## The problem
|
|
9
|
+
|
|
10
|
+
Claude Recall's LLM classifier originally called Claude Haiku through the
|
|
11
|
+
Anthropic SDK, which needs `ANTHROPIC_API_KEY` — a **personal pay-as-you-go
|
|
12
|
+
key**. For a long time the docs claimed Claude Code "provides the key to its
|
|
13
|
+
hooks." That was false: Claude Code does not mint a key from the user's
|
|
14
|
+
subscription; hooks merely inherit the user's environment. So the key path
|
|
15
|
+
only ever worked for users who had exported their own key, and it silently
|
|
16
|
+
spent **their API credits** — a separate wallet from the Claude subscription
|
|
17
|
+
they were already paying for.
|
|
18
|
+
|
|
19
|
+
The failure mode that exposed all of this: a user's exported key ran out of
|
|
20
|
+
credits. Every SDK call failed silently, capture degraded to the regex
|
|
21
|
+
fallback, and the regex promptly stored four junk memories in one session —
|
|
22
|
+
while the user reasonably believed "the LLM" was doing the classifying.
|
|
23
|
+
|
|
24
|
+
## The finding
|
|
25
|
+
|
|
26
|
+
**`claude -p "<prompt>"` is a headless one-shot completion that runs on the
|
|
27
|
+
user's Claude Code login** — the direct analogue of the earlier
|
|
28
|
+
`kiro-cli chat --no-interactive` discovery. A background worker can shell out
|
|
29
|
+
to it to classify text with no API key and no extra cost beyond the
|
|
30
|
+
subscription usage the user already has.
|
|
31
|
+
|
|
32
|
+
One gotcha made this non-trivial, and it's the most important line in the
|
|
33
|
+
implementation:
|
|
34
|
+
|
|
35
|
+
> **`claude -p` prefers `ANTHROPIC_API_KEY` over subscription auth when the
|
|
36
|
+
> key is present in the environment.**
|
|
37
|
+
|
|
38
|
+
So a stray exported key — possibly dead, possibly billing a wallet the user
|
|
39
|
+
forgot about — would silently hijack every headless call. The fix:
|
|
40
|
+
`completeWithClaudeCli()` **strips `ANTHROPIC_API_KEY` from the child env**,
|
|
41
|
+
forcing subscription auth unconditionally. (Verified live: with a
|
|
42
|
+
credits-exhausted key in the env, `claude -p` returned
|
|
43
|
+
`Credit balance is too low`; with the key stripped, the same call succeeded on
|
|
44
|
+
the login.)
|
|
45
|
+
|
|
46
|
+
## The design
|
|
47
|
+
|
|
48
|
+
```
|
|
49
|
+
Claude Code UserPromptSubmit
|
|
50
|
+
│
|
|
51
|
+
▼
|
|
52
|
+
hook run correction-detector (name unchanged in settings.json;
|
|
53
|
+
│ returns in <100 ms)
|
|
54
|
+
│ spawn detached, pipe payload via stdin
|
|
55
|
+
▼
|
|
56
|
+
hook run cc-capture-worker (background, survives parent exit)
|
|
57
|
+
│ sets CLAUDE_RECALL_CC_CLASSIFIER=1
|
|
58
|
+
▼
|
|
59
|
+
handleCorrectionDetector → classifyContent()
|
|
60
|
+
│
|
|
61
|
+
├─ classifyWithClaudeCli() → claude -p --model haiku "<prompt>"
|
|
62
|
+
│ (subscription auth, key stripped)
|
|
63
|
+
└─ regex fallback
|
|
64
|
+
|
|
65
|
+
(classifyWithLLM() / ANTHROPIC_API_KEY exists but is OPT-IN only —
|
|
66
|
+
see below; it is never in the default chain)
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
Precedence mirrors Kiro: **the runtime's included LLM → regex.** An exported
|
|
70
|
+
`ANTHROPIC_API_KEY` is **never consulted by default — not even as a
|
|
71
|
+
fallback**; `CLAUDE_RECALL_PREFER_API_KEY=1` is the one switch that enables
|
|
72
|
+
(and prefers) it. The registered hook name (`hook run correction-detector`)
|
|
73
|
+
was deliberately kept, so existing `settings.json` files work with no
|
|
74
|
+
re-setup — only the dispatch behind it changed.
|
|
75
|
+
|
|
76
|
+
**Trade-off:** the synchronous `📌 Recall: auto-captured …` echo is gone.
|
|
77
|
+
A cold `claude -p` takes ~4 s, far too slow to block the user's prompt, so
|
|
78
|
+
capture is silent and lands a few seconds later — the same contract Kiro has
|
|
79
|
+
always had. Verify via `~/.claude-recall/hook-logs/cc-classifier.log`
|
|
80
|
+
(`classified via claude -p (model=…, Claude subscription, no API key)`) or
|
|
81
|
+
`claude-recall search`.
|
|
82
|
+
|
|
83
|
+
### Recursion guard
|
|
84
|
+
|
|
85
|
+
The nested headless session is itself a Claude Code session. If the user has
|
|
86
|
+
claude-recall hooks registered at **user scope** (`~/.claude/settings.json`),
|
|
87
|
+
the classify call would fire those hooks, which would spawn another worker,
|
|
88
|
+
which would run another `claude -p` — forever. Two layers prevent this:
|
|
89
|
+
|
|
90
|
+
1. `claude -p` children run with `cwd = os.tmpdir()`, so **project**
|
|
91
|
+
settings/hooks never load.
|
|
92
|
+
2. Children are marked with `CLAUDE_RECALL_NESTED=1` (plus the legacy
|
|
93
|
+
`CLAUDE_RECALL_CC_CLASSIFIER=1`). The capture hook refuses to spawn a
|
|
94
|
+
worker, and the secondary-feature backend refuses to invoke the CLI, when
|
|
95
|
+
either marker is present.
|
|
96
|
+
|
|
97
|
+
### Beyond capture: the secondary features (0.32.0)
|
|
98
|
+
|
|
99
|
+
`completeWithClaudeCli()` is a generic completion primitive, and the four
|
|
100
|
+
features that previously knew only the key path now route through it with the
|
|
101
|
+
same precedence:
|
|
102
|
+
|
|
103
|
+
| Feature | Runs in | Without any key, now |
|
|
104
|
+
| --- | --- | --- |
|
|
105
|
+
| Auto-checkpoint extraction | Session-exit worker (CC + **Pi** — Pi's only recovery path, it has no `--resume`) | Works via `claude -p` |
|
|
106
|
+
| Failure hindsight hints | Stop hook, inline | Works via `claude -p` |
|
|
107
|
+
| End-of-session lesson extraction | Stop hook, inline | Works via `claude -p` |
|
|
108
|
+
| Batch classification | Stop hook, inline | Works via `claude -p` |
|
|
109
|
+
|
|
110
|
+
Two budget rules keep the inline ones inside the Stop hook's ~40 s window
|
|
111
|
+
(capture doesn't need them — it runs in a detached worker):
|
|
112
|
+
|
|
113
|
+
- each secondary CLI call is capped at **10 s** (vs the worker's 30 s), and
|
|
114
|
+
- hindsight-hint generation is capped at **5 LLM calls per run** (the loop
|
|
115
|
+
over detected failures is otherwise unbounded; failures past the cap keep
|
|
116
|
+
the grounded generic lesson text).
|
|
117
|
+
|
|
118
|
+
Under **Pi** these functions run in-process, so Pi benefits automatically on
|
|
119
|
+
any machine with the `claude` binary installed alongside. Under **Kiro** the
|
|
120
|
+
Stop-hook features mostly don't run (no transcript in its hooks), and capture
|
|
121
|
+
uses the Kiro backend.
|
|
122
|
+
|
|
123
|
+
### Configuration
|
|
124
|
+
|
|
125
|
+
| Variable | Default | Effect |
|
|
126
|
+
| --- | --- | --- |
|
|
127
|
+
| `CLAUDE_RECALL_CC_MODEL` | `haiku` | Model passed to `claude -p --model` — a dedicated classifier model, independent of the user's interactive session model. |
|
|
128
|
+
| `CLAUDE_RECALL_CC_LLM_TIMEOUT_MS` | `30000` | Hard cap on the capture worker's `claude -p` call. (Secondary features use a fixed 10 s per call.) |
|
|
129
|
+
| `CLAUDE_RECALL_PREFER_API_KEY` | *(unset)* | **The only switch that enables the `ANTHROPIC_API_KEY` backend** (and prefers it first) — without it an exported key is never touched, not even as a fallback. For Pi-only machines without the `claude` binary, or a stronger model you deliberately pay for. Applies to capture and the secondary features, on every runtime. |
|
|
130
|
+
| `CLAUDE_RECALL_NESTED` | *(set on `claude -p` children)* | Recursion marker — never set it by hand. |
|
|
131
|
+
|
|
132
|
+
## Caveats
|
|
133
|
+
|
|
134
|
+
- **Requires the `claude` binary on `PATH`.** Absent (e.g. a bare CI box, or a
|
|
135
|
+
Pi-only machine), the CLI backend errors out and the chain falls through to
|
|
136
|
+
regex — or to an `ANTHROPIC_API_KEY` if you opted in with
|
|
137
|
+
`CLAUDE_RECALL_PREFER_API_KEY=1`. No crash, no exception.
|
|
138
|
+
- **Subscription usage.** Each classified prompt is one small Haiku call
|
|
139
|
+
against the user's Claude plan limits. That is the deliberate trade — the
|
|
140
|
+
user's existing plan instead of a second wallet.
|
|
141
|
+
- **Latency.** ~4 s cold per call. Fine in a detached worker; the reason the
|
|
142
|
+
inline features carry the 10 s cap and hint budget.
|
|
143
|
+
- **Consistency.** Same probabilistic caveat as the Kiro backend: the
|
|
144
|
+
classifier is an LLM judgement call. The classify prompt carries a
|
|
145
|
+
"standalone rule" test with negative examples precisely because early
|
|
146
|
+
versions stored one-off task instructions ("first fix the sentence") as
|
|
147
|
+
corrections.
|
package/docs/kiro-llm-capture.md
CHANGED
|
@@ -9,7 +9,7 @@ Claude Haiku through `ANTHROPIC_API_KEY` — a personal API key the user had
|
|
|
9
9
|
exported themselves. (Claude Code does **not** mint a key from the user's
|
|
10
10
|
subscription; hooks merely inherit the environment. The headless-CLI approach
|
|
11
11
|
documented here was later applied back to Claude Code via `claude -p` on
|
|
12
|
-
subscription auth — see
|
|
12
|
+
subscription auth — see [cc-llm-capture.md](cc-llm-capture.md).)
|
|
13
13
|
|
|
14
14
|
Kiro CLI does **not** set `ANTHROPIC_API_KEY`. So under Kiro the classifier fell
|
|
15
15
|
back to a conservative regex that only fires on explicit phrasings
|
|
@@ -89,20 +89,24 @@ Kiro userPromptSubmit
|
|
|
89
89
|
▼
|
|
90
90
|
handleCorrectionDetector → classifyContent()
|
|
91
91
|
│
|
|
92
|
-
├─ classifyWithLLM() → ANTHROPIC_API_KEY (unset under Kiro) → null
|
|
93
92
|
├─ classifyWithKiro() → kiro-cli chat --no-interactive --agent
|
|
94
93
|
│ claude-recall-classifier --model claude-haiku-4.5
|
|
95
94
|
│ → {"type","confidence","extract"}
|
|
96
|
-
└─ regex fallback (only if
|
|
95
|
+
└─ regex fallback (only if the above yields nothing)
|
|
96
|
+
|
|
97
|
+
(classifyWithLLM() / ANTHROPIC_API_KEY exists but is OPT-IN only —
|
|
98
|
+
never in the default chain)
|
|
97
99
|
```
|
|
98
100
|
|
|
99
|
-
Capture precedence under Kiro: **Kiro's included LLM →
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
Anthropic credits
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
101
|
+
Capture precedence under Kiro: **Kiro's included LLM → regex as a last
|
|
102
|
+
resort.** An exported `ANTHROPIC_API_KEY` is **never consulted by default —
|
|
103
|
+
not even as a fallback** — so a key exported for other tools never silently
|
|
104
|
+
spends the user's Anthropic credits; Kiro already ships an LLM.
|
|
105
|
+
`CLAUDE_RECALL_PREFER_API_KEY=1` is the one explicit switch that enables (and
|
|
106
|
+
prefers) the key, for anyone who deliberately wants to pay for a stronger
|
|
107
|
+
model. (Under Claude Code the same pattern applies with `claude -p` on the
|
|
108
|
+
user's subscription as the included LLM — see
|
|
109
|
+
[cc-llm-capture.md](cc-llm-capture.md).)
|
|
106
110
|
|
|
107
111
|
### Output parsing
|
|
108
112
|
|
|
@@ -119,7 +123,7 @@ returns `null`, degrading to regex — a hook must never throw.
|
|
|
119
123
|
| `CLAUDE_RECALL_KIRO_CLASSIFIER` | *(set by the worker)* | Enables the Kiro-LLM path in `classifyContent`. Set automatically by `kiro-capture-worker`; never needed by hand. |
|
|
120
124
|
| `CLAUDE_RECALL_KIRO_MODEL` | `claude-haiku-4.5` | Model for the classify call, passed explicitly as `--model`. This is a **dedicated classifier model, independent of the user's interactive Kiro chat model** (e.g. `auto`) — the headless call always uses this value. Raise to `claude-sonnet-4.6` for steadier judgement at ~3× the credits. |
|
|
121
125
|
| `CLAUDE_RECALL_KIRO_LLM_TIMEOUT_MS` | `30000` | Hard cap on the headless call before the worker gives up and falls back to regex. |
|
|
122
|
-
| `CLAUDE_RECALL_PREFER_API_KEY` | *(unset)* |
|
|
126
|
+
| `CLAUDE_RECALL_PREFER_API_KEY` | *(unset)* | **The only switch that enables the `ANTHROPIC_API_KEY` backend** — without it an exported key is never touched, not even as a fallback. |
|
|
123
127
|
|
|
124
128
|
## Caveats
|
|
125
129
|
|
package/docs/kiro.md
CHANGED
|
@@ -74,7 +74,7 @@ To decide what's worth remembering, the capture hook classifies each prompt via
|
|
|
74
74
|
|
|
75
75
|
**The classifier uses a dedicated, fixed model — not your chat model.** It always runs the model in `CLAUDE_RECALL_KIRO_MODEL` (default `claude-haiku-4.5`, chosen because classification is cheap and high-volume), **independent of your interactive Kiro chat model** (e.g. `auto`). This keeps classification cost predictable no matter what your chat is set to. Set `CLAUDE_RECALL_KIRO_MODEL` to any model from `kiro-cli chat --list-models` to change it. Every successful classification is logged to `~/.claude-recall/hook-logs/kiro-classifier.log` as `classified via kiro-cli (model=…, Kiro credits, no API key)`, so you can always see which model ran.
|
|
76
76
|
|
|
77
|
-
**
|
|
77
|
+
**An exported `ANTHROPIC_API_KEY` is never touched** — a key exported for other tools won't quietly spend your Anthropic credits, not even as a fallback. Order: Kiro's LLM → regex. Setting `CLAUDE_RECALL_PREFER_API_KEY=1` is the one explicit switch that enables (and prefers) your key, e.g. for a stronger model you pay for.
|
|
78
78
|
|
|
79
79
|
Design details, latency measurements, and output-parsing internals: [kiro-llm-capture.md](kiro-llm-capture.md).
|
|
80
80
|
|
package/package.json
CHANGED