clementine-agent 1.0.8 → 1.0.9

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 CHANGED
@@ -434,6 +434,43 @@ ENABLE_1M_CONTEXT=false # Enable 1M token context for Sonnet (toggle in dashb
434
434
 
435
435
  Secrets can also be stored in macOS Keychain (`security find-generic-password`) — Clementine checks Keychain as a fallback for any missing `.env` value.
436
436
 
437
+ ### Tuning Clementine
438
+
439
+ Clementine ships with sensible defaults. To change anything, use:
440
+
441
+ ```bash
442
+ clementine config set <KEY> <value> # writes to ~/.clementine/.env
443
+ clementine config get <KEY>
444
+ clementine config list # show all overrides
445
+ clementine restart # apply changes
446
+ ```
447
+
448
+ Your overrides live in `~/.clementine/.env` — **they survive every `npm update -g` / `clementine update`** because they're in your data home, not the package directory.
449
+
450
+ **Commonly tuned knobs:**
451
+
452
+ | Key | Default | What it does |
453
+ |-----|---------|--------------|
454
+ | `BUDGET_CHAT_USD` | `5.00` | Max spend per interactive chat message |
455
+ | `BUDGET_CRON_T1_USD` | `2.00` | Max spend per tier-1 cron job |
456
+ | `BUDGET_CRON_T2_USD` | `5.00` | Max spend per tier-2 cron job |
457
+ | `BUDGET_HEARTBEAT_USD` | `0.50` | Max spend per heartbeat tick |
458
+ | `DEFAULT_MODEL_TIER` | `sonnet` | Default model: `haiku` / `sonnet` / `opus` |
459
+ | `ENABLE_1M_CONTEXT` | `false` | Enable Sonnet 1M-token context (beta) |
460
+ | `HEARTBEAT_INTERVAL_MINUTES` | `30` | How often the agent auto-checks in |
461
+ | `HEARTBEAT_ACTIVE_START` | `8` | First hour of the active window (0–23) |
462
+ | `HEARTBEAT_ACTIVE_END` | `22` | Last hour of the active window |
463
+ | `TIMEZONE` | system TZ | IANA timezone string (e.g., `America/Los_Angeles`) |
464
+ | `ALLOW_ALL_USERS` | `false` | `true` = skip owner-only gate (trust all DMs) |
465
+ | `ASSISTANT_NAME` | `Clementine` | Display name across channels |
466
+
467
+ Example — raise the chat budget to `$10` without ever touching source:
468
+
469
+ ```bash
470
+ clementine config set BUDGET_CHAT_USD 10
471
+ clementine restart
472
+ ```
473
+
437
474
  ---
438
475
 
439
476
  ## Models
@@ -1966,7 +1966,10 @@ You have a cost budget per message — not a hard turn limit. Work until the tas
1966
1966
  const lower = errorText.toLowerCase();
1967
1967
  if (lower.includes('max_budget_usd') || lower.includes('budget')) {
1968
1968
  logger.warn({ sessionKey }, 'Chat query hit budget cap');
1969
- responseText = responseText || 'I hit the cost limit for this query. Try breaking it into smaller requests.';
1969
+ responseText = responseText || (`I hit the $${BUDGET.chat.toFixed(2)} cost cap for this query. Options:\n` +
1970
+ `• Break it into smaller requests\n` +
1971
+ `• Reply "deep mode" to queue this as a background task with a bigger budget\n` +
1972
+ `• Raise the cap permanently: \`clementine config set BUDGET_CHAT_USD 10\` then \`clementine restart\``);
1970
1973
  }
1971
1974
  else if (lower.includes('rate') && lower.includes('limit')) {
1972
1975
  hitRateLimit = true;
package/dist/config.d.ts CHANGED
@@ -39,14 +39,14 @@ export declare const OWNER_NAME: string;
39
39
  export declare function shellEscape(s: string): string;
40
40
  export declare const MODELS: Models;
41
41
  export declare const BUDGET: {
42
- readonly heartbeat: 0.5;
43
- readonly cronT1: 2;
44
- readonly cronT2: 5;
45
- readonly chat: 5;
46
- readonly unleashedPhase: undefined;
47
- readonly memoryExtraction: undefined;
48
- readonly summarization: undefined;
49
- readonly reflection: undefined;
42
+ heartbeat: number;
43
+ cronT1: number;
44
+ cronT2: number;
45
+ chat: number;
46
+ unleashedPhase: undefined;
47
+ memoryExtraction: undefined;
48
+ summarization: undefined;
49
+ reflection: undefined;
50
50
  };
51
51
  export declare const DEFAULT_MODEL_TIER: keyof Models;
52
52
  export declare const MODEL: string;
package/dist/config.js CHANGED
@@ -98,11 +98,13 @@ export const MODELS = {
98
98
  opus: 'claude-opus-4-6',
99
99
  };
100
100
  // ── Budget caps (USD per query) ──────────────────────────────────────
101
+ // User-tunable via `clementine config set BUDGET_<NAME>_USD <value>`
102
+ // (writes to ~/.clementine/.env, survives npm update -g).
101
103
  export const BUDGET = {
102
- heartbeat: 0.50, // $0.50 per heartbeat (Haiku, cheap)
103
- cronT1: 2.00, // $2 per tier-1 cron job (needs room for outlook+search)
104
- cronT2: 5.00, // $5 per tier-2 cron job
105
- chat: 5.00, // $5 per interactive chat message
104
+ heartbeat: Number(getEnv('BUDGET_HEARTBEAT_USD', '0.50')), // per heartbeat (Haiku)
105
+ cronT1: Number(getEnv('BUDGET_CRON_T1_USD', '2.00')), // per tier-1 cron job
106
+ cronT2: Number(getEnv('BUDGET_CRON_T2_USD', '5.00')), // per tier-2 cron job
107
+ chat: Number(getEnv('BUDGET_CHAT_USD', '5.00')), // per interactive chat
106
108
  unleashedPhase: undefined,
107
109
  memoryExtraction: undefined,
108
110
  summarization: undefined,
@@ -1137,7 +1137,7 @@ export function registerAdminTools(server) {
1137
1137
  // ── Source Self-Edit Tools ──────────────────────────────────────────────
1138
1138
  const SELF_IMPROVE_DIR = path.join(BASE_DIR, 'self-improve');
1139
1139
  const PENDING_SOURCE_DIR = path.join(SELF_IMPROVE_DIR, 'pending-source-changes');
1140
- server.tool('self_edit_source', 'Edit Clementine source code safely. Validates in a staging worktree, commits, builds, and triggers restart only if compilation succeeds. The daemon picks up the pending change and executes it.', {
1140
+ server.tool('self_edit_source', 'Edit most Clementine TypeScript source files (for new features or bug fixes). Validates in a staging worktree, compiles, and triggers restart on success. Blocked files: `src/config.ts`, `src/gateway/security-scanner.ts`, `src/security/scanner.ts`. Do NOT use this tool to change user-tunable settings (budget caps, model tier, heartbeat interval, timezone, channel IDs, etc.) — those live in `~/.clementine/.env` and are managed by the user via `clementine config set KEY value`, which survives `clementine update` / `npm update -g`.', {
1141
1141
  file: z.string().describe('Path relative to src/ (e.g., "channels/discord-agent-bot.ts")'),
1142
1142
  content: z.string().describe('Complete new file content'),
1143
1143
  reason: z.string().describe('Why this change is being made'),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "clementine-agent",
3
- "version": "1.0.8",
3
+ "version": "1.0.9",
4
4
  "description": "Clementine — Personal AI Assistant (TypeScript)",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",