bernard-agent 0.1.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.
Files changed (112) hide show
  1. package/.env.example +21 -0
  2. package/LICENSE +21 -0
  3. package/README.md +629 -0
  4. package/dist/agent.d.ts +24 -0
  5. package/dist/agent.js +174 -0
  6. package/dist/agent.js.map +1 -0
  7. package/dist/config.d.ts +44 -0
  8. package/dist/config.js +267 -0
  9. package/dist/config.js.map +1 -0
  10. package/dist/context.d.ts +37 -0
  11. package/dist/context.js +245 -0
  12. package/dist/context.js.map +1 -0
  13. package/dist/cron/client.d.ts +4 -0
  14. package/dist/cron/client.js +113 -0
  15. package/dist/cron/client.js.map +1 -0
  16. package/dist/cron/daemon.d.ts +1 -0
  17. package/dist/cron/daemon.js +132 -0
  18. package/dist/cron/daemon.js.map +1 -0
  19. package/dist/cron/log-store.d.ts +51 -0
  20. package/dist/cron/log-store.js +135 -0
  21. package/dist/cron/log-store.js.map +1 -0
  22. package/dist/cron/notify.d.ts +7 -0
  23. package/dist/cron/notify.js +136 -0
  24. package/dist/cron/notify.js.map +1 -0
  25. package/dist/cron/runner.d.ts +6 -0
  26. package/dist/cron/runner.js +219 -0
  27. package/dist/cron/runner.js.map +1 -0
  28. package/dist/cron/scheduler.d.ts +16 -0
  29. package/dist/cron/scheduler.js +105 -0
  30. package/dist/cron/scheduler.js.map +1 -0
  31. package/dist/cron/store.d.ts +20 -0
  32. package/dist/cron/store.js +170 -0
  33. package/dist/cron/store.js.map +1 -0
  34. package/dist/cron/types.d.ts +21 -0
  35. package/dist/cron/types.js +3 -0
  36. package/dist/cron/types.js.map +1 -0
  37. package/dist/embeddings.d.ts +14 -0
  38. package/dist/embeddings.js +61 -0
  39. package/dist/embeddings.js.map +1 -0
  40. package/dist/history.d.ts +6 -0
  41. package/dist/history.js +71 -0
  42. package/dist/history.js.map +1 -0
  43. package/dist/index.d.ts +2 -0
  44. package/dist/index.js +231 -0
  45. package/dist/index.js.map +1 -0
  46. package/dist/logger.d.ts +1 -0
  47. package/dist/logger.js +24 -0
  48. package/dist/logger.js.map +1 -0
  49. package/dist/mcp.d.ts +43 -0
  50. package/dist/mcp.js +303 -0
  51. package/dist/mcp.js.map +1 -0
  52. package/dist/memory.d.ts +17 -0
  53. package/dist/memory.js +106 -0
  54. package/dist/memory.js.map +1 -0
  55. package/dist/output.d.ts +13 -0
  56. package/dist/output.js +151 -0
  57. package/dist/output.js.map +1 -0
  58. package/dist/providers/index.d.ts +2 -0
  59. package/dist/providers/index.js +19 -0
  60. package/dist/providers/index.js.map +1 -0
  61. package/dist/providers/types.d.ts +5 -0
  62. package/dist/providers/types.js +3 -0
  63. package/dist/providers/types.js.map +1 -0
  64. package/dist/rag-worker.d.ts +10 -0
  65. package/dist/rag-worker.js +84 -0
  66. package/dist/rag-worker.js.map +1 -0
  67. package/dist/rag.d.ts +53 -0
  68. package/dist/rag.js +242 -0
  69. package/dist/rag.js.map +1 -0
  70. package/dist/repl.d.ts +2 -0
  71. package/dist/repl.js +531 -0
  72. package/dist/repl.js.map +1 -0
  73. package/dist/setup.d.ts +1 -0
  74. package/dist/setup.js +104 -0
  75. package/dist/setup.js.map +1 -0
  76. package/dist/tools/cron-logs.d.ts +67 -0
  77. package/dist/tools/cron-logs.js +131 -0
  78. package/dist/tools/cron-logs.js.map +1 -0
  79. package/dist/tools/cron.d.ts +98 -0
  80. package/dist/tools/cron.js +248 -0
  81. package/dist/tools/cron.js.map +1 -0
  82. package/dist/tools/datetime.d.ts +4 -0
  83. package/dist/tools/datetime.js +25 -0
  84. package/dist/tools/datetime.js.map +1 -0
  85. package/dist/tools/index.d.ts +317 -0
  86. package/dist/tools/index.js +28 -0
  87. package/dist/tools/index.js.map +1 -0
  88. package/dist/tools/mcp-url.d.ts +16 -0
  89. package/dist/tools/mcp-url.js +27 -0
  90. package/dist/tools/mcp-url.js.map +1 -0
  91. package/dist/tools/mcp.d.ts +28 -0
  92. package/dist/tools/mcp.js +107 -0
  93. package/dist/tools/mcp.js.map +1 -0
  94. package/dist/tools/memory.d.ts +40 -0
  95. package/dist/tools/memory.js +99 -0
  96. package/dist/tools/memory.js.map +1 -0
  97. package/dist/tools/shell.d.ts +15 -0
  98. package/dist/tools/shell.js +60 -0
  99. package/dist/tools/shell.js.map +1 -0
  100. package/dist/tools/subagent.d.ts +21 -0
  101. package/dist/tools/subagent.js +81 -0
  102. package/dist/tools/subagent.js.map +1 -0
  103. package/dist/tools/time.d.ts +50 -0
  104. package/dist/tools/time.js +61 -0
  105. package/dist/tools/time.js.map +1 -0
  106. package/dist/tools/types.d.ts +8 -0
  107. package/dist/tools/types.js +3 -0
  108. package/dist/tools/types.js.map +1 -0
  109. package/dist/tools/web.d.ts +16 -0
  110. package/dist/tools/web.js +136 -0
  111. package/dist/tools/web.js.map +1 -0
  112. package/package.json +73 -0
package/dist/agent.js ADDED
@@ -0,0 +1,174 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Agent = void 0;
4
+ exports.buildSystemPrompt = buildSystemPrompt;
5
+ const ai_1 = require("ai");
6
+ const index_js_1 = require("./providers/index.js");
7
+ const index_js_2 = require("./tools/index.js");
8
+ const subagent_js_1 = require("./tools/subagent.js");
9
+ const output_js_1 = require("./output.js");
10
+ const logger_js_1 = require("./logger.js");
11
+ const context_js_1 = require("./context.js");
12
+ const BASE_SYSTEM_PROMPT = `You are Bernard, a helpful AI assistant with shell access. You can execute terminal commands to help users with their tasks.
13
+
14
+ Guidelines:
15
+ - Use the shell tool to run commands when the user asks about files, git, processes, or anything requiring terminal access.
16
+ - Be concise in your responses.
17
+ - When showing command output, summarize the key points rather than repeating everything verbatim.
18
+ - If a command fails, explain what went wrong and suggest alternatives.
19
+ - Always confirm before running destructive commands (the tool will handle confirmation).
20
+ - You are running on the user's local machine. Be careful with commands that modify or delete data.
21
+ - Use the memory tool to persist important facts about the user or project that should be recalled in future sessions (e.g. preferences, project conventions, key decisions).
22
+ - Use the scratch tool to track progress on complex multi-step tasks within the current session. Scratch notes survive context compression but are discarded when the session ends.
23
+ - Use the cron_* tools (cron_create, cron_list, cron_get, cron_update, cron_delete, cron_enable, cron_disable, cron_status) to manage scheduled background tasks for recurring checks, monitoring, or periodic tasks. Jobs run in a background daemon and can use the notify tool to alert the user when attention is needed.
24
+ - Use the cron_logs_* tools (cron_logs_list, cron_logs_get, cron_logs_summary, cron_logs_cleanup) to review execution logs from cron job runs.
25
+ - Use the web_read tool to fetch and read web pages. Give it a URL and it returns the page content as markdown. Useful for reading documentation, articles, Stack Overflow answers, GitHub pages, or any URL the user shares or that appears in error messages.
26
+ - Use the agent tool to delegate independent subtasks to parallel sub-agents. Each sub-agent gets its own tool set and works independently. Call the agent tool multiple times in a single response to run tasks in parallel. Good use cases: researching multiple topics simultaneously, running independent shell commands in parallel, analyzing different files at the same time. Do NOT use sub-agents for sequential tasks that depend on each other's results — just do those yourself step by step.
27
+ - Your context may include a "Recalled Context" section with observations from past sessions. These are automatically retrieved — only reference them if directly relevant to what the user is asking.`;
28
+ /** @internal */
29
+ function buildSystemPrompt(config, memoryStore, mcpServerNames, ragResults) {
30
+ const today = new Date().toLocaleDateString('en-US', {
31
+ weekday: 'long', year: 'numeric', month: 'long', day: 'numeric',
32
+ });
33
+ let prompt = BASE_SYSTEM_PROMPT + `\n\nToday's date is ${today}.`;
34
+ prompt += `\nYou are running as provider: ${config.provider}, model: ${config.model}. The user can switch with /provider and /model.`;
35
+ if (ragResults && ragResults.length > 0) {
36
+ prompt += '\n\n## Recalled Context\nThe following are automatically recalled observations from previous conversations.\nReference them only if directly relevant to the current discussion.';
37
+ for (const r of ragResults) {
38
+ prompt += `\n- ${r.fact}`;
39
+ }
40
+ }
41
+ const memories = memoryStore.getAllMemoryContents();
42
+ if (memories.size > 0) {
43
+ prompt += '\n\n## Persistent Memory\n';
44
+ for (const [key, content] of memories) {
45
+ prompt += `\n### ${key}\n${content}\n`;
46
+ }
47
+ }
48
+ const scratch = memoryStore.getAllScratchContents();
49
+ if (scratch.size > 0) {
50
+ prompt += '\n\n## Scratch Notes (session only)\n';
51
+ for (const [key, content] of scratch) {
52
+ prompt += `\n### ${key}\n${content}\n`;
53
+ }
54
+ }
55
+ prompt += `\n\n## MCP Servers
56
+
57
+ MCP (Model Context Protocol) servers provide additional tools. Use the mcp_config tool to manage stdio-based MCP servers (command + args). Use the mcp_add_url tool to add URL-based MCP servers (SSE/HTTP endpoints) — just give it a name and URL. Changes take effect after restarting Bernard.`;
58
+ if (mcpServerNames && mcpServerNames.length > 0) {
59
+ prompt += `\n\nCurrently connected MCP servers: ${mcpServerNames.join(', ')}`;
60
+ }
61
+ else {
62
+ prompt += '\n\nNo MCP servers are currently connected.';
63
+ }
64
+ return prompt;
65
+ }
66
+ class Agent {
67
+ history = [];
68
+ config;
69
+ toolOptions;
70
+ memoryStore;
71
+ mcpTools;
72
+ mcpServerNames;
73
+ alertContext;
74
+ ragStore;
75
+ abortController = null;
76
+ lastPromptTokens = 0;
77
+ constructor(config, toolOptions, memoryStore, mcpTools, mcpServerNames, alertContext, initialHistory, ragStore) {
78
+ this.config = config;
79
+ this.toolOptions = toolOptions;
80
+ this.memoryStore = memoryStore;
81
+ this.mcpTools = mcpTools;
82
+ this.mcpServerNames = mcpServerNames;
83
+ this.alertContext = alertContext;
84
+ this.ragStore = ragStore;
85
+ if (initialHistory) {
86
+ this.history = [...initialHistory];
87
+ this.lastPromptTokens = Math.ceil(JSON.stringify(initialHistory).length / 4);
88
+ }
89
+ }
90
+ getHistory() {
91
+ return this.history;
92
+ }
93
+ abort() {
94
+ this.abortController?.abort();
95
+ }
96
+ async processInput(userInput) {
97
+ this.history.push({ role: 'user', content: userInput });
98
+ this.abortController = new AbortController();
99
+ try {
100
+ // Check if context compression is needed
101
+ const newMessageEstimate = Math.ceil(userInput.length / 4);
102
+ if ((0, context_js_1.shouldCompress)(this.lastPromptTokens, newMessageEstimate, this.config.model)) {
103
+ (0, output_js_1.printInfo)('Compressing conversation context...');
104
+ this.history = await (0, context_js_1.compressHistory)(this.history, this.config, this.ragStore);
105
+ }
106
+ // RAG search for relevant memories
107
+ let ragResults;
108
+ if (this.ragStore) {
109
+ try {
110
+ ragResults = await this.ragStore.search(userInput);
111
+ if (ragResults.length > 0) {
112
+ (0, logger_js_1.debugLog)('agent:rag', { query: userInput.slice(0, 100), results: ragResults.length });
113
+ }
114
+ }
115
+ catch (err) {
116
+ (0, logger_js_1.debugLog)('agent:rag:error', err instanceof Error ? err.message : String(err));
117
+ }
118
+ }
119
+ let systemPrompt = buildSystemPrompt(this.config, this.memoryStore, this.mcpServerNames, ragResults);
120
+ if (this.alertContext) {
121
+ systemPrompt += '\n\n' + this.alertContext;
122
+ }
123
+ const baseTools = (0, index_js_2.createTools)(this.toolOptions, this.memoryStore, this.mcpTools);
124
+ const tools = {
125
+ ...baseTools,
126
+ agent: (0, subagent_js_1.createSubAgentTool)(this.config, this.toolOptions, this.memoryStore, this.mcpTools),
127
+ };
128
+ const result = await (0, ai_1.generateText)({
129
+ model: (0, index_js_1.getModel)(this.config.provider, this.config.model),
130
+ tools,
131
+ maxSteps: 20,
132
+ maxTokens: this.config.maxTokens,
133
+ system: systemPrompt,
134
+ messages: this.history,
135
+ abortSignal: this.abortController.signal,
136
+ onStepFinish: ({ text, toolCalls, toolResults }) => {
137
+ for (const tc of toolCalls) {
138
+ (0, logger_js_1.debugLog)(`onStepFinish:toolCall:${tc.toolName}`, tc.args);
139
+ (0, output_js_1.printToolCall)(tc.toolName, tc.args);
140
+ }
141
+ for (const tr of toolResults) {
142
+ (0, logger_js_1.debugLog)(`onStepFinish:toolResult:${tr.toolName}`, tr.result);
143
+ (0, output_js_1.printToolResult)(tr.toolName, tr.result);
144
+ }
145
+ if (text) {
146
+ (0, output_js_1.printAssistantText)(text);
147
+ }
148
+ },
149
+ });
150
+ // Track token usage for compression decisions
151
+ if (result.usage?.promptTokens) {
152
+ this.lastPromptTokens = result.usage.promptTokens;
153
+ }
154
+ // Append all response messages to history for continuity
155
+ this.history.push(...result.response.messages);
156
+ }
157
+ catch (err) {
158
+ // If aborted by user, return silently — user message stays in history
159
+ if (this.abortController?.signal.aborted)
160
+ return;
161
+ const message = err instanceof Error ? err.message : String(err);
162
+ throw new Error(`Agent error: ${message}`);
163
+ }
164
+ finally {
165
+ this.abortController = null;
166
+ }
167
+ }
168
+ clearHistory() {
169
+ this.history = [];
170
+ this.memoryStore.clearScratch();
171
+ }
172
+ }
173
+ exports.Agent = Agent;
174
+ //# sourceMappingURL=agent.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent.js","sourceRoot":"","sources":["../src/agent.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,44 @@
1
+ export interface BernardConfig {
2
+ provider: string;
3
+ model: string;
4
+ maxTokens: number;
5
+ shellTimeout: number;
6
+ ragEnabled: boolean;
7
+ anthropicApiKey?: string;
8
+ openaiApiKey?: string;
9
+ xaiApiKey?: string;
10
+ }
11
+ export declare const PROVIDER_ENV_VARS: Record<string, string>;
12
+ export declare const OPTIONS_REGISTRY: Record<string, {
13
+ configKey: 'maxTokens' | 'shellTimeout';
14
+ default: number;
15
+ description: string;
16
+ envVar: string;
17
+ }>;
18
+ export declare function savePreferences(prefs: {
19
+ provider: string;
20
+ model: string;
21
+ maxTokens?: number;
22
+ shellTimeout?: number;
23
+ }): void;
24
+ export declare function loadPreferences(): {
25
+ provider?: string;
26
+ model?: string;
27
+ maxTokens?: number;
28
+ shellTimeout?: number;
29
+ };
30
+ export declare function saveProviderKey(provider: string, key: string): void;
31
+ export declare function saveOption(name: string, value: number): void;
32
+ export declare function resetOption(name: string): void;
33
+ export declare function resetAllOptions(): void;
34
+ export declare function getProviderKeyStatus(): Array<{
35
+ provider: string;
36
+ hasKey: boolean;
37
+ }>;
38
+ export declare const PROVIDER_MODELS: Record<string, string[]>;
39
+ export declare function getDefaultModel(provider: string): string;
40
+ export declare function getAvailableProviders(config: BernardConfig): string[];
41
+ export declare function loadConfig(overrides?: {
42
+ provider?: string;
43
+ model?: string;
44
+ }): BernardConfig;
package/dist/config.js ADDED
@@ -0,0 +1,267 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.PROVIDER_MODELS = exports.OPTIONS_REGISTRY = exports.PROVIDER_ENV_VARS = void 0;
37
+ exports.savePreferences = savePreferences;
38
+ exports.loadPreferences = loadPreferences;
39
+ exports.saveProviderKey = saveProviderKey;
40
+ exports.saveOption = saveOption;
41
+ exports.resetOption = resetOption;
42
+ exports.resetAllOptions = resetAllOptions;
43
+ exports.getProviderKeyStatus = getProviderKeyStatus;
44
+ exports.getDefaultModel = getDefaultModel;
45
+ exports.getAvailableProviders = getAvailableProviders;
46
+ exports.loadConfig = loadConfig;
47
+ const dotenv = __importStar(require("dotenv"));
48
+ const path = __importStar(require("node:path"));
49
+ const os = __importStar(require("node:os"));
50
+ const fs = __importStar(require("node:fs"));
51
+ const DEFAULT_PROVIDER = 'anthropic';
52
+ const DEFAULT_MAX_TOKENS = 4096;
53
+ const DEFAULT_SHELL_TIMEOUT = 30000;
54
+ const PREFS_PATH = path.join(os.homedir(), '.bernard', 'preferences.json');
55
+ const KEYS_PATH = path.join(os.homedir(), '.bernard', 'keys.json');
56
+ exports.PROVIDER_ENV_VARS = {
57
+ anthropic: 'ANTHROPIC_API_KEY',
58
+ openai: 'OPENAI_API_KEY',
59
+ xai: 'XAI_API_KEY',
60
+ };
61
+ exports.OPTIONS_REGISTRY = {
62
+ 'max-tokens': {
63
+ configKey: 'maxTokens',
64
+ default: DEFAULT_MAX_TOKENS,
65
+ description: 'Maximum tokens per AI response (controls response length)',
66
+ envVar: 'BERNARD_MAX_TOKENS',
67
+ },
68
+ 'shell-timeout': {
69
+ configKey: 'shellTimeout',
70
+ default: DEFAULT_SHELL_TIMEOUT,
71
+ description: 'Shell command timeout in milliseconds (how long commands can run)',
72
+ envVar: 'BERNARD_SHELL_TIMEOUT',
73
+ },
74
+ };
75
+ function savePreferences(prefs) {
76
+ const dir = path.dirname(PREFS_PATH);
77
+ if (!fs.existsSync(dir)) {
78
+ fs.mkdirSync(dir, { recursive: true });
79
+ }
80
+ const data = { provider: prefs.provider, model: prefs.model };
81
+ if (prefs.maxTokens !== undefined)
82
+ data.maxTokens = prefs.maxTokens;
83
+ if (prefs.shellTimeout !== undefined)
84
+ data.shellTimeout = prefs.shellTimeout;
85
+ fs.writeFileSync(PREFS_PATH, JSON.stringify(data, null, 2) + '\n');
86
+ }
87
+ function loadPreferences() {
88
+ try {
89
+ const data = fs.readFileSync(PREFS_PATH, 'utf-8');
90
+ const parsed = JSON.parse(data);
91
+ return {
92
+ provider: typeof parsed.provider === 'string' ? parsed.provider : undefined,
93
+ model: typeof parsed.model === 'string' ? parsed.model : undefined,
94
+ maxTokens: typeof parsed.maxTokens === 'number' ? parsed.maxTokens : undefined,
95
+ shellTimeout: typeof parsed.shellTimeout === 'number' ? parsed.shellTimeout : undefined,
96
+ };
97
+ }
98
+ catch {
99
+ return {};
100
+ }
101
+ }
102
+ function loadStoredKeys() {
103
+ try {
104
+ const data = fs.readFileSync(KEYS_PATH, 'utf-8');
105
+ const parsed = JSON.parse(data);
106
+ if (typeof parsed === 'object' && parsed !== null) {
107
+ return parsed;
108
+ }
109
+ return {};
110
+ }
111
+ catch {
112
+ return {};
113
+ }
114
+ }
115
+ function saveProviderKey(provider, key) {
116
+ if (!exports.PROVIDER_ENV_VARS[provider]) {
117
+ throw new Error(`Unknown provider "${provider}". Supported: ${Object.keys(exports.PROVIDER_ENV_VARS).join(', ')}`);
118
+ }
119
+ const dir = path.dirname(KEYS_PATH);
120
+ if (!fs.existsSync(dir)) {
121
+ fs.mkdirSync(dir, { recursive: true });
122
+ }
123
+ const existing = loadStoredKeys();
124
+ existing[provider] = key;
125
+ fs.writeFileSync(KEYS_PATH, JSON.stringify(existing, null, 2) + '\n');
126
+ fs.chmodSync(KEYS_PATH, 0o600);
127
+ }
128
+ function saveOption(name, value) {
129
+ const entry = exports.OPTIONS_REGISTRY[name];
130
+ if (!entry) {
131
+ throw new Error(`Unknown option "${name}". Valid options: ${Object.keys(exports.OPTIONS_REGISTRY).join(', ')}`);
132
+ }
133
+ const prefs = loadPreferences();
134
+ prefs[entry.configKey] = value;
135
+ savePreferences({
136
+ provider: prefs.provider || 'anthropic',
137
+ model: prefs.model || getDefaultModel(prefs.provider || 'anthropic'),
138
+ maxTokens: prefs.maxTokens,
139
+ shellTimeout: prefs.shellTimeout,
140
+ });
141
+ }
142
+ function resetOption(name) {
143
+ const entry = exports.OPTIONS_REGISTRY[name];
144
+ if (!entry) {
145
+ throw new Error(`Unknown option "${name}". Valid options: ${Object.keys(exports.OPTIONS_REGISTRY).join(', ')}`);
146
+ }
147
+ const prefs = loadPreferences();
148
+ delete prefs[entry.configKey];
149
+ savePreferences({
150
+ provider: prefs.provider || 'anthropic',
151
+ model: prefs.model || getDefaultModel(prefs.provider || 'anthropic'),
152
+ maxTokens: prefs.maxTokens,
153
+ shellTimeout: prefs.shellTimeout,
154
+ });
155
+ }
156
+ function resetAllOptions() {
157
+ const prefs = loadPreferences();
158
+ delete prefs.maxTokens;
159
+ delete prefs.shellTimeout;
160
+ savePreferences({
161
+ provider: prefs.provider || 'anthropic',
162
+ model: prefs.model || getDefaultModel(prefs.provider || 'anthropic'),
163
+ });
164
+ }
165
+ function getProviderKeyStatus() {
166
+ const cwdEnv = path.join(process.cwd(), '.env');
167
+ const homeEnv = path.join(os.homedir(), '.bernard', '.env');
168
+ if (fs.existsSync(cwdEnv)) {
169
+ dotenv.config({ path: cwdEnv });
170
+ }
171
+ else if (fs.existsSync(homeEnv)) {
172
+ dotenv.config({ path: homeEnv });
173
+ }
174
+ const storedKeys = loadStoredKeys();
175
+ return Object.entries(exports.PROVIDER_ENV_VARS).map(([provider, envVar]) => ({
176
+ provider,
177
+ hasKey: !!(storedKeys[provider] || process.env[envVar]),
178
+ }));
179
+ }
180
+ exports.PROVIDER_MODELS = {
181
+ anthropic: [
182
+ 'claude-sonnet-4-5-20250929',
183
+ 'claude-opus-4-20250514',
184
+ 'claude-sonnet-4-20250514',
185
+ 'claude-3-5-haiku-latest',
186
+ ],
187
+ openai: [
188
+ 'gpt-4o',
189
+ 'gpt-4o-mini',
190
+ 'o3',
191
+ 'o3-mini',
192
+ 'o4-mini',
193
+ 'gpt-4.1',
194
+ 'gpt-4.1-mini',
195
+ 'gpt-4.1-nano',
196
+ ],
197
+ xai: [
198
+ 'grok-3',
199
+ 'grok-3-fast',
200
+ 'grok-3-mini',
201
+ 'grok-3-mini-fast',
202
+ ],
203
+ };
204
+ function getDefaultModel(provider) {
205
+ return exports.PROVIDER_MODELS[provider]?.[0] ?? exports.PROVIDER_MODELS[DEFAULT_PROVIDER][0];
206
+ }
207
+ function getAvailableProviders(config) {
208
+ const keyMap = {
209
+ anthropic: config.anthropicApiKey,
210
+ openai: config.openaiApiKey,
211
+ xai: config.xaiApiKey,
212
+ };
213
+ return Object.keys(exports.PROVIDER_MODELS).filter((p) => !!keyMap[p]);
214
+ }
215
+ function loadConfig(overrides) {
216
+ // Load .env from cwd first, then fallback to ~/.bernard/.env
217
+ const cwdEnv = path.join(process.cwd(), '.env');
218
+ const homeEnv = path.join(os.homedir(), '.bernard', '.env');
219
+ if (fs.existsSync(cwdEnv)) {
220
+ dotenv.config({ path: cwdEnv });
221
+ }
222
+ else if (fs.existsSync(homeEnv)) {
223
+ dotenv.config({ path: homeEnv });
224
+ }
225
+ // Stored keys override .env — user explicitly ran `add-key`
226
+ const storedKeys = loadStoredKeys();
227
+ for (const [provider, key] of Object.entries(storedKeys)) {
228
+ const envVar = exports.PROVIDER_ENV_VARS[provider];
229
+ if (envVar && key)
230
+ process.env[envVar] = key;
231
+ }
232
+ const prefs = loadPreferences();
233
+ const provider = overrides?.provider || prefs.provider || process.env.BERNARD_PROVIDER || DEFAULT_PROVIDER;
234
+ const model = overrides?.model || prefs.model || process.env.BERNARD_MODEL || getDefaultModel(provider);
235
+ const maxTokens = prefs.maxTokens
236
+ ?? (parseInt(process.env.BERNARD_MAX_TOKENS || '', 10) || DEFAULT_MAX_TOKENS);
237
+ const shellTimeout = prefs.shellTimeout
238
+ ?? (parseInt(process.env.BERNARD_SHELL_TIMEOUT || '', 10) || DEFAULT_SHELL_TIMEOUT);
239
+ const ragEnabled = process.env.BERNARD_RAG_ENABLED !== 'false';
240
+ const config = {
241
+ provider,
242
+ model,
243
+ maxTokens,
244
+ shellTimeout,
245
+ ragEnabled,
246
+ anthropicApiKey: process.env.ANTHROPIC_API_KEY,
247
+ openaiApiKey: process.env.OPENAI_API_KEY,
248
+ xaiApiKey: process.env.XAI_API_KEY,
249
+ };
250
+ validateConfig(config);
251
+ return config;
252
+ }
253
+ function validateConfig(config) {
254
+ const keyMap = {
255
+ anthropic: config.anthropicApiKey,
256
+ openai: config.openaiApiKey,
257
+ xai: config.xaiApiKey,
258
+ };
259
+ const key = keyMap[config.provider];
260
+ if (!key) {
261
+ const envVar = exports.PROVIDER_ENV_VARS[config.provider];
262
+ throw new Error(`No API key found for provider "${config.provider}". ` +
263
+ `Run: bernard add-key ${config.provider} <your-api-key>\n` +
264
+ `Or set ${envVar} in your .env file or environment.`);
265
+ }
266
+ }
267
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,37 @@
1
+ import { type CoreMessage } from 'ai';
2
+ import type { BernardConfig } from './config.js';
3
+ import type { RAGStore } from './rag.js';
4
+ /** Model name → context window size in tokens */
5
+ export declare const MODEL_CONTEXT_WINDOWS: Record<string, number>;
6
+ export declare const DEFAULT_CONTEXT_WINDOW = 128000;
7
+ export declare const COMPRESSION_THRESHOLD = 0.75;
8
+ export declare const RECENT_TURNS_TO_KEEP = 4;
9
+ /** Look up context window for a model, falling back to 128k for unknown models. */
10
+ export declare function getContextWindow(model: string): number;
11
+ /**
12
+ * Returns true when estimated token usage exceeds the compression threshold.
13
+ * @param lastPromptTokens - actual prompt token count from the last API call
14
+ * @param newMessageEstimate - rough token estimate for the new user message
15
+ * @param model - model name for context window lookup
16
+ */
17
+ export declare function shouldCompress(lastPromptTokens: number, newMessageEstimate: number, model: string): boolean;
18
+ /** Convert a CoreMessage array into readable text for the summarizer. */
19
+ export declare function serializeMessages(messages: CoreMessage[]): string;
20
+ /**
21
+ * Walk backward through history to find the split point that keeps the last N
22
+ * user/assistant exchanges intact.
23
+ * Returns the index where "recent" messages start (0 means nothing to compress).
24
+ */
25
+ export declare function countRecentMessages(history: CoreMessage[], turnsToKeep: number): number;
26
+ /**
27
+ * Extract notable facts from serialized conversation text via LLM.
28
+ * Returns an empty array on any failure.
29
+ * @internal
30
+ */
31
+ export declare function extractFacts(serializedText: string, config: BernardConfig): Promise<string[]>;
32
+ /**
33
+ * Compress conversation history by summarizing older messages via the LLM.
34
+ * Keeps the most recent turns intact and replaces older messages with a summary.
35
+ * On failure, returns the original history unchanged.
36
+ */
37
+ export declare function compressHistory(history: CoreMessage[], config: BernardConfig, ragStore?: RAGStore): Promise<CoreMessage[]>;