claude-memory-admin 1.11.2 → 1.12.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/package.json +1 -1
- package/public/views/cost.mjs +6 -4
- package/src/cost.mjs +28 -3
package/package.json
CHANGED
package/public/views/cost.mjs
CHANGED
|
@@ -64,15 +64,16 @@ function picker(options, current, onPick) {
|
|
|
64
64
|
|
|
65
65
|
for (const option of all) {
|
|
66
66
|
control.append(node('option', {
|
|
67
|
-
value: option.value === null ? '' : option.value,
|
|
67
|
+
value: option.value === null ? '' : String(option.value),
|
|
68
68
|
text: optionText(option),
|
|
69
69
|
}));
|
|
70
70
|
}
|
|
71
|
-
control.value = current === null || current === undefined ? '' : current;
|
|
71
|
+
control.value = current === null || current === undefined ? '' : String(current);
|
|
72
72
|
|
|
73
73
|
control.addEventListener('change', () => {
|
|
74
74
|
control.disabled = true;
|
|
75
|
-
|
|
75
|
+
const picked = all.find((option) => option.value !== null && String(option.value) === control.value);
|
|
76
|
+
onPick(picked ? picked.value : null);
|
|
76
77
|
});
|
|
77
78
|
return control;
|
|
78
79
|
}
|
|
@@ -143,6 +144,7 @@ function settingCard(entry, writable) {
|
|
|
143
144
|
text: entry.effective ? show(entry.effective.value) : 'unset (default)',
|
|
144
145
|
}),
|
|
145
146
|
entry.effective ? node('span', { class: ui.scopeBadge(entry.effective.scope), text: entry.effective.scope }) : null,
|
|
147
|
+
entry.offRecommendation ? node('span', { class: ui.badge('warn'), text: `costs tokens - ${entry.recommended} recommended` }) : null,
|
|
146
148
|
]));
|
|
147
149
|
card.append(node('p', { class: ui.noteTight, text: entry.detail }));
|
|
148
150
|
|
|
@@ -246,7 +248,7 @@ export async function renderCost(container) {
|
|
|
246
248
|
|
|
247
249
|
container.append(node('p', {
|
|
248
250
|
class: ui.noteTight,
|
|
249
|
-
text: `The
|
|
251
|
+
text: `The settings that decide what a session costs, and the model each of your agents runs on. This is the one place in the app that writes outside a memory store: changes land in ${data.settings.userFile} and in the files under ${data.agentsDir}. Your CLAUDE.md and the rest of the instruction chain are never touched.`,
|
|
250
252
|
}));
|
|
251
253
|
|
|
252
254
|
for (const problem of data.settings.problems) {
|
package/src/cost.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
// The
|
|
2
|
-
//
|
|
1
|
+
// The settings keys that decide what a session costs, and the only keys this
|
|
2
|
+
// tool ever writes.
|
|
3
3
|
//
|
|
4
4
|
// Everything else in the app reports; this module changes ~/.claude/settings.json.
|
|
5
5
|
// That is a deliberate exception, so the surface is kept as narrow as it can be:
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
// and a hard refusal to rewrite a settings file that did not parse - overwriting
|
|
8
8
|
// one would silently drop every setting this tool could not read.
|
|
9
9
|
//
|
|
10
|
-
// The
|
|
10
|
+
// The keys:
|
|
11
11
|
//
|
|
12
12
|
// env.CLAUDE_CODE_SUBAGENT_MODEL the model every subagent, agent-team member
|
|
13
13
|
// and workflow agent runs on. It outranks both
|
|
@@ -16,6 +16,9 @@
|
|
|
16
16
|
// outputStyle how Claude writes back in the main
|
|
17
17
|
// conversation. Subagents run their own system
|
|
18
18
|
// prompt and are untouched by it.
|
|
19
|
+
// promptSuggestionEnabled whether a suggested next prompt is generated
|
|
20
|
+
// after every turn. On by default, and it
|
|
21
|
+
// spends tokens whether anyone uses it or not.
|
|
19
22
|
|
|
20
23
|
import fs from 'node:fs';
|
|
21
24
|
import path from 'node:path';
|
|
@@ -75,6 +78,23 @@ export const COST_KEYS = [
|
|
|
75
78
|
{ value: 'Learning', label: 'Learning', note: 'longer answers' },
|
|
76
79
|
],
|
|
77
80
|
},
|
|
81
|
+
{
|
|
82
|
+
key: 'promptSuggestion',
|
|
83
|
+
path: ['promptSuggestionEnabled'],
|
|
84
|
+
label: 'promptSuggestionEnabled',
|
|
85
|
+
title: 'Prompt suggestions',
|
|
86
|
+
detail: 'Generates a suggested next prompt after every turn, which reads the conversation again. Mostly cached, but not free, and wasted if nobody accepts the suggestions. Turn it off unless you use them.',
|
|
87
|
+
envVar: null,
|
|
88
|
+
unset: 'Default',
|
|
89
|
+
allowModelId: false,
|
|
90
|
+
custom: null,
|
|
91
|
+
recommended: false,
|
|
92
|
+
options: [
|
|
93
|
+
{ value: null, label: 'Default', note: 'unset - on' },
|
|
94
|
+
{ value: false, label: 'false', note: 'saves tokens' },
|
|
95
|
+
{ value: true, label: 'true' },
|
|
96
|
+
],
|
|
97
|
+
},
|
|
78
98
|
];
|
|
79
99
|
|
|
80
100
|
/**
|
|
@@ -123,6 +143,7 @@ function optionsFor(descriptor, outputStyles) {
|
|
|
123
143
|
*/
|
|
124
144
|
export function normaliseCostValue(descriptor, value, outputStyles = []) {
|
|
125
145
|
if (value === null || value === undefined) return null;
|
|
146
|
+
if (typeof value === 'boolean' && descriptor.options.some((option) => option.value === value)) return value;
|
|
126
147
|
if (typeof value !== 'string') {
|
|
127
148
|
throw new Error(`${descriptor.label} takes a string, not ${Array.isArray(value) ? 'a list' : typeof value}.`);
|
|
128
149
|
}
|
|
@@ -224,6 +245,10 @@ export function costReport(options = {}) {
|
|
|
224
245
|
shadowedByStronger: Boolean(winner && winner.scope !== 'user'),
|
|
225
246
|
envVar: descriptor.envVar,
|
|
226
247
|
envValue,
|
|
248
|
+
recommended: descriptor.recommended,
|
|
249
|
+
// Unset means the built-in default, which for every recommended key is on.
|
|
250
|
+
offRecommendation: descriptor.recommended !== undefined
|
|
251
|
+
&& (winner ? winner.value : true) !== descriptor.recommended,
|
|
227
252
|
};
|
|
228
253
|
});
|
|
229
254
|
|