bernard-agent 0.3.1 → 0.5.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 (138) hide show
  1. package/README.md +109 -38
  2. package/THIRD-PARTY-NOTICES +212 -0
  3. package/dist/agent.d.ts +32 -3
  4. package/dist/agent.js +63 -12
  5. package/dist/agent.js.map +1 -1
  6. package/dist/config.d.ts +67 -0
  7. package/dist/config.js +99 -31
  8. package/dist/config.js.map +1 -1
  9. package/dist/context.d.ts +7 -0
  10. package/dist/context.js +32 -20
  11. package/dist/context.js.map +1 -1
  12. package/dist/cron/cli.d.ts +7 -0
  13. package/dist/cron/cli.js +61 -5
  14. package/dist/cron/cli.js.map +1 -1
  15. package/dist/cron/client.d.ts +9 -0
  16. package/dist/cron/client.js +9 -0
  17. package/dist/cron/client.js.map +1 -1
  18. package/dist/cron/daemon.js +12 -1
  19. package/dist/cron/daemon.js.map +1 -1
  20. package/dist/cron/log-store.d.ts +18 -0
  21. package/dist/cron/log-store.js +41 -18
  22. package/dist/cron/log-store.js.map +1 -1
  23. package/dist/cron/notify.d.ts +7 -0
  24. package/dist/cron/notify.js +16 -0
  25. package/dist/cron/notify.js.map +1 -1
  26. package/dist/cron/runner.d.ts +11 -0
  27. package/dist/cron/runner.js +77 -20
  28. package/dist/cron/runner.js.map +1 -1
  29. package/dist/cron/scheduler.d.ts +16 -0
  30. package/dist/cron/scheduler.js +24 -7
  31. package/dist/cron/scheduler.js.map +1 -1
  32. package/dist/cron/store.d.ts +32 -0
  33. package/dist/cron/store.js +64 -27
  34. package/dist/cron/store.js.map +1 -1
  35. package/dist/cron/types.d.ts +19 -0
  36. package/dist/domains.d.ts +15 -0
  37. package/dist/domains.js +20 -1
  38. package/dist/domains.js.map +1 -1
  39. package/dist/embeddings.d.ts +7 -1
  40. package/dist/embeddings.js +43 -1
  41. package/dist/embeddings.js.map +1 -1
  42. package/dist/facts-cli.d.ts +14 -0
  43. package/dist/facts-cli.js +55 -1
  44. package/dist/facts-cli.js.map +1 -1
  45. package/dist/history.d.ts +8 -0
  46. package/dist/history.js +14 -9
  47. package/dist/history.js.map +1 -1
  48. package/dist/index.d.ts +5 -0
  49. package/dist/index.js +36 -2
  50. package/dist/index.js.map +1 -1
  51. package/dist/logger.d.ts +6 -0
  52. package/dist/logger.js +6 -0
  53. package/dist/logger.js.map +1 -1
  54. package/dist/mcp.d.ts +87 -0
  55. package/dist/mcp.js +116 -39
  56. package/dist/mcp.js.map +1 -1
  57. package/dist/memory-context.d.ts +4 -0
  58. package/dist/memory-context.js +4 -1
  59. package/dist/memory-context.js.map +1 -1
  60. package/dist/memory.d.ts +17 -0
  61. package/dist/memory.js +24 -10
  62. package/dist/memory.js.map +1 -1
  63. package/dist/migrate.d.ts +13 -0
  64. package/dist/migrate.js +209 -0
  65. package/dist/migrate.js.map +1 -0
  66. package/dist/output.d.ts +46 -1
  67. package/dist/output.js +72 -11
  68. package/dist/output.js.map +1 -1
  69. package/dist/paths.d.ts +23 -0
  70. package/dist/paths.js +82 -0
  71. package/dist/paths.js.map +1 -0
  72. package/dist/providers/index.d.ts +7 -0
  73. package/dist/providers/index.js +7 -0
  74. package/dist/providers/index.js.map +1 -1
  75. package/dist/providers/types.d.ts +4 -0
  76. package/dist/rag-query.d.ts +20 -0
  77. package/dist/rag-query.js +70 -6
  78. package/dist/rag-query.js.map +1 -1
  79. package/dist/rag-worker.js.map +1 -1
  80. package/dist/rag.d.ts +41 -1
  81. package/dist/rag.js +125 -21
  82. package/dist/rag.js.map +1 -1
  83. package/dist/repl.d.ts +6 -0
  84. package/dist/repl.js +211 -44
  85. package/dist/repl.js.map +1 -1
  86. package/dist/routines.d.ts +49 -0
  87. package/dist/routines.js +172 -0
  88. package/dist/routines.js.map +1 -0
  89. package/dist/setup.d.ts +5 -0
  90. package/dist/setup.js +8 -2
  91. package/dist/setup.js.map +1 -1
  92. package/dist/theme.d.ts +41 -0
  93. package/dist/theme.js +55 -5
  94. package/dist/theme.js.map +1 -1
  95. package/dist/tools/cron-logs.d.ts +6 -0
  96. package/dist/tools/cron-logs.js +17 -4
  97. package/dist/tools/cron-logs.js.map +1 -1
  98. package/dist/tools/cron.d.ts +18 -0
  99. package/dist/tools/cron.js +67 -11
  100. package/dist/tools/cron.js.map +1 -1
  101. package/dist/tools/datetime.d.ts +1 -0
  102. package/dist/tools/datetime.js +1 -0
  103. package/dist/tools/datetime.js.map +1 -1
  104. package/dist/tools/index.d.ts +10 -325
  105. package/dist/tools/index.js +11 -1
  106. package/dist/tools/index.js.map +1 -1
  107. package/dist/tools/mcp-url.d.ts +6 -0
  108. package/dist/tools/mcp-url.js +6 -0
  109. package/dist/tools/mcp-url.js.map +1 -1
  110. package/dist/tools/mcp.d.ts +6 -0
  111. package/dist/tools/mcp.js +25 -12
  112. package/dist/tools/mcp.js.map +1 -1
  113. package/dist/tools/memory.d.ts +14 -0
  114. package/dist/tools/memory.js +18 -3
  115. package/dist/tools/memory.js.map +1 -1
  116. package/dist/tools/routine.d.ts +35 -0
  117. package/dist/tools/routine.js +93 -0
  118. package/dist/tools/routine.js.map +1 -0
  119. package/dist/tools/shell.d.ts +15 -1
  120. package/dist/tools/shell.js +16 -2
  121. package/dist/tools/shell.js.map +1 -1
  122. package/dist/tools/subagent.d.ts +18 -1
  123. package/dist/tools/subagent.js +27 -7
  124. package/dist/tools/subagent.js.map +1 -1
  125. package/dist/tools/time.d.ts +19 -0
  126. package/dist/tools/time.js +27 -4
  127. package/dist/tools/time.js.map +1 -1
  128. package/dist/tools/types.d.ts +6 -0
  129. package/dist/tools/wait.d.ts +3 -0
  130. package/dist/tools/wait.js +3 -0
  131. package/dist/tools/wait.js.map +1 -1
  132. package/dist/tools/web.d.ts +6 -0
  133. package/dist/tools/web.js +29 -6
  134. package/dist/tools/web.js.map +1 -1
  135. package/dist/update.d.ts +5 -0
  136. package/dist/update.js +8 -7
  137. package/dist/update.js.map +1 -1
  138. package/package.json +11 -2
package/README.md CHANGED
@@ -24,6 +24,7 @@ A local CLI AI agent that executes terminal commands, manages scheduled tasks, r
24
24
  - [Date and Time](#date-and-time)
25
25
  - [Time Range Calculations](#time-range-calculations)
26
26
  - [Sub-Agents](#sub-agents)
27
+ - [Routines](#routines)
27
28
  - [Cron Jobs (Scheduled Tasks)](#cron-jobs-scheduled-tasks)
28
29
  - [Creating Jobs](#creating-jobs)
29
30
  - [Managing Jobs](#managing-jobs)
@@ -46,6 +47,7 @@ A local CLI AI agent that executes terminal commands, manages scheduled tasks, r
46
47
  - [Adding a New Tool](#adding-a-new-tool)
47
48
  - [Contributing](#contributing)
48
49
  - [Bug Reports](#bug-reports)
50
+ - [Third-Party Licenses](#third-party-licenses)
49
51
  - [License](#license)
50
52
 
51
53
  ---
@@ -122,25 +124,25 @@ bernard providers
122
124
 
123
125
  Bernard loads `.env` from the current directory first, then falls back to `~/.bernard/.env`.
124
126
 
125
- | Variable | Description | Default |
126
- |----------|-------------|---------|
127
- | `BERNARD_PROVIDER` | LLM provider (`anthropic`, `openai`, `xai`) | `anthropic` |
128
- | `BERNARD_MODEL` | Model name | Provider-specific default |
129
- | `BERNARD_MAX_TOKENS` | Max response tokens | `4096` |
130
- | `BERNARD_SHELL_TIMEOUT` | Shell command timeout (ms) | `30000` |
131
- | `BERNARD_RAG_ENABLED` | Enable the RAG memory system | `true` |
132
- | `BERNARD_DEBUG` | Enable debug logging | unset |
133
- | `ANTHROPIC_API_KEY` | Anthropic API key | — |
134
- | `OPENAI_API_KEY` | OpenAI API key | — |
135
- | `XAI_API_KEY` | xAI API key | — |
127
+ | Variable | Description | Default |
128
+ | ----------------------- | ------------------------------------------- | ------------------------- |
129
+ | `BERNARD_PROVIDER` | LLM provider (`anthropic`, `openai`, `xai`) | `anthropic` |
130
+ | `BERNARD_MODEL` | Model name | Provider-specific default |
131
+ | `BERNARD_MAX_TOKENS` | Max response tokens | `4096` |
132
+ | `BERNARD_SHELL_TIMEOUT` | Shell command timeout (ms) | `30000` |
133
+ | `BERNARD_RAG_ENABLED` | Enable the RAG memory system | `true` |
134
+ | `BERNARD_DEBUG` | Enable debug logging | unset |
135
+ | `ANTHROPIC_API_KEY` | Anthropic API key | — |
136
+ | `OPENAI_API_KEY` | OpenAI API key | — |
137
+ | `XAI_API_KEY` | xAI API key | — |
136
138
 
137
139
  ### Providers and Models
138
140
 
139
- | Provider | Default Model | Available Models |
140
- |----------|--------------|------------------|
141
+ | Provider | Default Model | Available Models |
142
+ | ----------- | ---------------------------- | ------------------------------------------------------------------------------------------------------------- |
141
143
  | `anthropic` | `claude-sonnet-4-5-20250929` | `claude-sonnet-4-5-20250929`, `claude-opus-4-20250514`, `claude-sonnet-4-20250514`, `claude-3-5-haiku-latest` |
142
- | `openai` | `gpt-4o` | `gpt-4o`, `gpt-4o-mini`, `o3`, `o3-mini`, `o4-mini`, `gpt-4.1`, `gpt-4.1-mini`, `gpt-4.1-nano` |
143
- | `xai` | `grok-3` | `grok-3`, `grok-3-fast`, `grok-3-mini`, `grok-3-mini-fast` |
144
+ | `openai` | `gpt-4o` | `gpt-4o`, `gpt-4o-mini`, `o3`, `o3-mini`, `o4-mini`, `gpt-4.1`, `gpt-4.1-mini`, `gpt-4.1-nano` |
145
+ | `xai` | `grok-3` | `grok-3`, `grok-3-fast`, `grok-3-mini`, `grok-3-mini-fast` |
144
146
 
145
147
  You can switch providers and models at any time during a session with `/provider` and `/model`.
146
148
 
@@ -148,9 +150,9 @@ You can switch providers and models at any time during a session with `/provider
148
150
 
149
151
  Options can be changed during a session with `/options` or persisted to `~/.bernard/preferences.json`:
150
152
 
151
- | Option | Default | Description |
152
- |--------|---------|-------------|
153
- | `max-tokens` | `4096` | Maximum tokens per AI response |
153
+ | Option | Default | Description |
154
+ | --------------- | ------- | ------------------------------------- |
155
+ | `max-tokens` | `4096` | Maximum tokens per AI response |
154
156
  | `shell-timeout` | `30000` | Shell command timeout in milliseconds |
155
157
 
156
158
  From the CLI:
@@ -174,12 +176,12 @@ bernard -r # Resume previous conversation
174
176
  bernard --alert <id> # Open with cron alert context
175
177
  ```
176
178
 
177
- | Flag | Description |
178
- |------|-------------|
179
+ | Flag | Description |
180
+ | ----------------------- | ------------------------------------- |
179
181
  | `-p, --provider <name>` | LLM provider (anthropic, openai, xai) |
180
- | `-m, --model <name>` | Model name |
181
- | `-r, --resume` | Resume the previous conversation |
182
- | `--alert <id>` | Load context from a cron alert |
182
+ | `-m, --model <name>` | Model name |
183
+ | `-r, --resume` | Resume the previous conversation |
184
+ | `--alert <id>` | Load context from a cron alert |
183
185
 
184
186
  ### CLI Management Commands
185
187
 
@@ -195,6 +197,7 @@ bernard remove-mcp <key> # Remove an MCP server
195
197
 
196
198
  # Cron management
197
199
  bernard cron-list # List all cron jobs with status
200
+ bernard cron-run <id> # Manually run a cron job immediately
198
201
  bernard cron-delete <ids...> # Delete specific cron jobs by ID
199
202
  bernard cron-delete-all # Delete all cron jobs
200
203
  bernard cron-stop [ids...] # Stop the daemon (no args) or disable specific jobs
@@ -206,6 +209,7 @@ bernard cron-bounce [ids...] # Restart the daemon (no args) or bounce spec
206
209
  Once running, Bernard presents an interactive prompt where you type natural language requests. Bernard has access to a suite of tools it can call autonomously — shell commands, memory, web fetching, and more.
207
210
 
208
211
  Features:
212
+
209
213
  - **Multi-line paste support** — paste code blocks directly; Bernard detects bracket paste mode
210
214
  - **Live command hints** — type `/` and matching slash commands appear as suggestions
211
215
  - **Abort in progress** — press Escape to cancel an in-flight request
@@ -213,20 +217,24 @@ Features:
213
217
 
214
218
  ### REPL Slash Commands
215
219
 
216
- | Command | Description |
217
- |---------|-------------|
218
- | `/help` | Show available commands |
219
- | `/clear` | Clear conversation history and scratch notes |
220
- | `/memory` | List all persistent memories |
221
- | `/scratch` | List session scratch notes |
222
- | `/mcp` | List connected MCP servers and their tools |
223
- | `/cron` | Show cron jobs and daemon status |
224
- | `/rag` | Show RAG memory stats and recent facts |
225
- | `/provider` | Switch LLM provider interactively |
226
- | `/model` | Switch model for the current provider |
227
- | `/theme` | Switch color theme |
228
- | `/options` | View and modify runtime options |
229
- | `/exit` | Quit Bernard (also: `exit`, `quit`) |
220
+ | Command | Description |
221
+ | ----------------- | -------------------------------------------- |
222
+ | `/help` | Show available commands |
223
+ | `/clear` | Clear conversation history and scratch notes |
224
+ | `/memory` | List all persistent memories |
225
+ | `/scratch` | List session scratch notes |
226
+ | `/mcp` | List connected MCP servers and their tools |
227
+ | `/cron` | Show cron jobs and daemon status |
228
+ | `/rag` | Show RAG memory stats and recent facts |
229
+ | `/provider` | Switch LLM provider interactively |
230
+ | `/model` | Switch model for the current provider |
231
+ | `/theme` | Switch color theme |
232
+ | `/routines` | List saved routines |
233
+ | `/create-routine` | Create a routine with guided AI assistance |
234
+ | `/options` | View and modify runtime options |
235
+ | `/exit` | Quit Bernard (also: `exit`, `quit`) |
236
+
237
+ Type `/{routine-id}` to invoke a saved routine directly (e.g., `/deploy-staging`).
230
238
 
231
239
  Prefix with `\` to send a `/`-prefixed message as text instead of a command (e.g., `\/etc/hosts` sends the literal string).
232
240
 
@@ -325,6 +333,47 @@ bernard> check the disk usage on /, look up the weather in Austin, and count lin
325
333
 
326
334
  Up to 4 concurrent sub-agents. Each gets 10 max steps. Color-coded output in the terminal.
327
335
 
336
+ ### Routines
337
+
338
+ Named, persistent multi-step workflows that you can teach Bernard and later invoke with a slash command. Routines capture procedures — deploy scripts, release checklists, onboarding flows — as free-form markdown.
339
+
340
+ ```
341
+ bernard> save a routine called "deploy-staging" that runs our build, pushes the docker image, and updates the k8s deployment
342
+ ▶ routine: create { id: "deploy-staging", name: "Deploy to Staging", ... }
343
+
344
+ Routine "Deploy to Staging" (/deploy-staging) created.
345
+ ```
346
+
347
+ Invoke a routine by typing `/{routine-id}`:
348
+
349
+ ```
350
+ bernard> /deploy-staging
351
+ (Bernard follows the saved procedure with full tool access)
352
+
353
+ bernard> /deploy-staging to production
354
+ (Bernard follows the routine with "to production" as additional context)
355
+ ```
356
+
357
+ Manage routines:
358
+
359
+ ```
360
+ bernard> list my routines
361
+ ▶ routine: list
362
+
363
+ bernard> show the deploy-staging routine
364
+ ▶ routine: read { id: "deploy-staging" }
365
+
366
+ bernard> update the deploy-staging routine to add a rollback step
367
+ ▶ routine: update { id: "deploy-staging", content: "..." }
368
+
369
+ bernard> delete the deploy-staging routine
370
+ ▶ routine: delete { id: "deploy-staging" }
371
+ ```
372
+
373
+ Use `/routines` in the REPL for a quick list. Routine names also appear in the live hint/autocomplete system when typing `/`.
374
+
375
+ Storage: one JSON file per routine in `~/.local/share/bernard/routines/`. Max 100 routines. IDs must be lowercase kebab-case (1–60 chars).
376
+
328
377
  ---
329
378
 
330
379
  ## Cron Jobs (Scheduled Tasks)
@@ -361,6 +410,9 @@ bernard> disable the disk-check job
361
410
  bernard> update the api health check to run every 30 minutes instead
362
411
  ▶ cron_update: { id: "def456", schedule: "*/30 * * * *" }
363
412
 
413
+ bernard> run the api health check right now
414
+ ▶ cron_run: { id: "def456" }
415
+
364
416
  bernard> delete the disk-check job
365
417
  ▶ cron_delete: { id: "abc123" }
366
418
 
@@ -368,9 +420,15 @@ bernard> what's the cron daemon status?
368
420
  ▶ cron_status
369
421
  ```
370
422
 
423
+ You can also run jobs manually from the CLI without entering the REPL:
424
+
425
+ ```bash
426
+ bernard cron-run <id>
427
+ ```
428
+
371
429
  Use `/cron` in the REPL for a quick status overview.
372
430
 
373
- Available cron tools: `cron_create`, `cron_list`, `cron_get`, `cron_update`, `cron_delete`, `cron_enable`, `cron_disable`, `cron_status`, `cron_bounce`, `cron_logs_list`, `cron_logs_get`, `cron_logs_summary`, `cron_logs_cleanup`.
431
+ Available cron tools: `cron_create`, `cron_list`, `cron_run`, `cron_get`, `cron_update`, `cron_delete`, `cron_enable`, `cron_disable`, `cron_status`, `cron_bounce`, `cron_logs_list`, `cron_logs_get`, `cron_logs_summary`, `cron_logs_cleanup`.
374
432
 
375
433
  ### Execution Logs
376
434
 
@@ -415,6 +473,7 @@ bernard> add an MCP server for filesystem access using npx @modelcontextprotocol
415
473
  ```
416
474
 
417
475
  Resulting config:
476
+
418
477
  ```json
419
478
  {
420
479
  "mcpServers": {
@@ -436,6 +495,7 @@ bernard> add this MCP server: http://localhost:6288/web/sse
436
495
  ```
437
496
 
438
497
  Resulting config:
498
+
439
499
  ```json
440
500
  {
441
501
  "mcpServers": {
@@ -447,10 +507,12 @@ Resulting config:
447
507
  ```
448
508
 
449
509
  URL servers support optional fields:
510
+
450
511
  - `type` — `"sse"` (default) or `"http"` for Streamable HTTP transport
451
512
  - `headers` — for authentication tokens or custom headers
452
513
 
453
514
  Example with all fields:
515
+
454
516
  ```json
455
517
  {
456
518
  "mcpServers": {
@@ -477,6 +539,7 @@ bernard> remove the filesystem server
477
539
  ```
478
540
 
479
541
  From the CLI:
542
+
480
543
  ```bash
481
544
  bernard mcp-list # List all configured servers
482
545
  bernard remove-mcp <key> # Remove a server
@@ -554,6 +617,8 @@ Bernard stores all data in `~/.bernard/`:
554
617
  ├── mcp.json # MCP server configuration
555
618
  ├── conversation-history.json # Last session (for --resume)
556
619
  ├── memory/ # Persistent memories (*.md)
620
+ ├── models/ # Embedding model cache (fastembed)
621
+ ├── routines/ # Saved routines (*.json)
557
622
  ├── rag/
558
623
  │ └── memories.json # RAG fact embeddings
559
624
  └── cron/
@@ -621,6 +686,7 @@ src/
621
686
  ├── domains.ts # Memory domain registry + extraction prompts
622
687
  ├── rag.ts # RAG store (domain-tagged embeddings + per-domain search)
623
688
  ├── embeddings.ts # FastEmbed wrapper
689
+ ├── routines.ts # RoutineStore (named multi-step workflows)
624
690
  ├── mcp.ts # MCP server manager
625
691
  ├── rag-worker.ts # Background RAG fact extraction worker
626
692
  ├── setup.ts # First-time setup wizard
@@ -641,6 +707,7 @@ src/
641
707
  │ ├── cron-logs.ts # Cron execution logs
642
708
  │ ├── mcp.ts # MCP config (stdio)
643
709
  │ ├── mcp-url.ts # MCP config (URL-based)
710
+ │ ├── routine.ts # Routine management tool
644
711
  │ └── subagent.ts # Parallel sub-agents
645
712
  └── cron/
646
713
  ├── cli.ts # Cron CLI subcommands
@@ -675,6 +742,10 @@ Found a bug? Please [open an issue](https://github.com/phillt/bernard/issues/new
675
742
  - Your environment (OS, Node version, Bernard version, provider/model)
676
743
  - Any relevant logs (run with `BERNARD_DEBUG=1` for verbose output)
677
744
 
745
+ ## Third-Party Licenses
746
+
747
+ Bernard uses the [all-MiniLM-L6-v2](https://huggingface.co/sentence-transformers/all-MiniLM-L6-v2) sentence-transformer model (via [fastembed](https://github.com/Anush008/fastembed-js)) for local RAG embeddings. This model is licensed under the Apache License 2.0. See [`THIRD-PARTY-NOTICES`](./THIRD-PARTY-NOTICES) for full license text and attribution.
748
+
678
749
  ## License
679
750
 
680
751
  MIT
@@ -0,0 +1,212 @@
1
+ Third-Party Licenses
2
+ ====================
3
+
4
+ all-MiniLM-L6-v2 (sentence-transformers)
5
+ -----------------------------------------
6
+ Source: https://huggingface.co/sentence-transformers/all-MiniLM-L6-v2
7
+ License: Apache License 2.0
8
+ Copyright: UKPLab / Nils Reimers
9
+
10
+ Used for local embedding computation in the RAG memory system via the
11
+ fastembed library (https://github.com/Anush008/fastembed-js).
12
+
13
+ Apache License
14
+ Version 2.0, January 2004
15
+ http://www.apache.org/licenses/
16
+
17
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
18
+
19
+ 1. Definitions.
20
+
21
+ "License" shall mean the terms and conditions for use, reproduction,
22
+ and distribution as defined by Sections 1 through 9 of this document.
23
+
24
+ "Licensor" shall mean the copyright owner or entity authorized by
25
+ the copyright owner that is granting the License.
26
+
27
+ "Legal Entity" shall mean the union of the acting entity and all
28
+ other entities that control, are controlled by, or are under common
29
+ control with that entity. For the purposes of this definition,
30
+ "control" means (i) the power, direct or indirect, to cause the
31
+ direction or management of such entity, whether by contract or
32
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
33
+ outstanding shares, or (iii) beneficial ownership of such entity.
34
+
35
+ "You" (or "Your") shall mean an individual or Legal Entity
36
+ exercising permissions granted by this License.
37
+
38
+ "Source" form shall mean the preferred form for making modifications,
39
+ including but not limited to software source code, documentation
40
+ source, and configuration files.
41
+
42
+ "Object" form shall mean any form resulting from mechanical
43
+ transformation or translation of a Source form, including but
44
+ not limited to compiled object code, generated documentation,
45
+ and conversions to other media types.
46
+
47
+ "Work" shall mean the work of authorship, whether in Source or
48
+ Object form, made available under the License, as indicated by a
49
+ copyright notice that is included in or attached to the work
50
+ (an example is provided in the Appendix below).
51
+
52
+ "Derivative Works" shall mean any work, whether in Source or Object
53
+ form, that is based on (or derived from) the Work and for which the
54
+ editorial revisions, annotations, elaborations, or other modifications
55
+ represent, as a whole, an original work of authorship. For the purposes
56
+ of this License, Derivative Works shall not include works that remain
57
+ separable from, or merely link (or bind by name) to the interfaces of,
58
+ the Work and Derivative Works thereof.
59
+
60
+ "Contribution" shall mean any work of authorship, including
61
+ the original version of the Work and any modifications or additions
62
+ to that Work or Derivative Works thereof, that is intentionally
63
+ submitted to the Licensor for inclusion in the Work by the copyright owner
64
+ or by an individual or Legal Entity authorized to submit on behalf of
65
+ the copyright owner. For the purposes of this definition, "submitted"
66
+ means any form of electronic, verbal, or written communication sent
67
+ to the Licensor or its representatives, including but not limited to
68
+ communication on electronic mailing lists, source code control systems,
69
+ and issue tracking systems that are managed by, or on behalf of, the
70
+ Licensor for the purpose of discussing and improving the Work, but
71
+ excluding communication that is conspicuously marked or otherwise
72
+ designated in writing by the copyright owner as "Not a Contribution."
73
+
74
+ "Contributor" shall mean Licensor and any individual or Legal Entity
75
+ on behalf of whom a Contribution has been received by the Licensor and
76
+ subsequently incorporated within the Work.
77
+
78
+ 2. Grant of Copyright License. Subject to the terms and conditions of
79
+ this License, each Contributor hereby grants to You a perpetual,
80
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
81
+ copyright license to reproduce, prepare Derivative Works of,
82
+ publicly display, publicly perform, sublicense, and distribute the
83
+ Work and such Derivative Works in Source or Object form.
84
+
85
+ 3. Grant of Patent License. Subject to the terms and conditions of
86
+ this License, each Contributor hereby grants to You a perpetual,
87
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
88
+ (except as stated in this section) patent license to make, have made,
89
+ use, offer to sell, sell, import, and otherwise transfer the Work,
90
+ where such license applies only to those patent claims licensable
91
+ by such Contributor that are necessarily infringed by their
92
+ Contribution(s) alone or by combination of their Contribution(s)
93
+ with the Work to which such Contribution(s) was submitted. If You
94
+ institute patent litigation against any entity (including a
95
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
96
+ or a Contribution incorporated within the Work constitutes direct
97
+ or contributory patent infringement, then any patent licenses
98
+ granted to You under this License for that Work shall terminate
99
+ as of the date such litigation is filed.
100
+
101
+ 4. Redistribution. You may reproduce and distribute copies of the
102
+ Work or Derivative Works thereof in any medium, with or without
103
+ modifications, and in Source or Object form, provided that You
104
+ meet the following conditions:
105
+
106
+ (a) You must give any other recipients of the Work or
107
+ Derivative Works a copy of this License; and
108
+
109
+ (b) You must cause any modified files to carry prominent notices
110
+ stating that You changed the files; and
111
+
112
+ (c) You must retain, in the Source form of any Derivative Works
113
+ that You distribute, all copyright, patent, trademark, and
114
+ attribution notices from the Source form of the Work,
115
+ excluding those notices that do not pertain to any part of
116
+ the Derivative Works; and
117
+
118
+ (d) If the Work includes a "NOTICE" text file as part of its
119
+ distribution, then any Derivative Works that You distribute must
120
+ include a readable copy of the attribution notices contained
121
+ within such NOTICE file, excluding any notices that do not
122
+ pertain to any part of the Derivative Works, in at least one
123
+ of the following places: within a NOTICE text file distributed
124
+ as part of the Derivative Works; within the Source form or
125
+ documentation, if provided along with the Derivative Works; or,
126
+ within a display generated by the Derivative Works, if and
127
+ wherever such third-party notices normally appear. The contents
128
+ of the NOTICE file are for informational purposes only and
129
+ do not modify the License. You may add Your own attribution
130
+ notices within Derivative Works that You distribute, alongside
131
+ or as an addendum to the NOTICE text from the Work, provided
132
+ that such additional attribution notices cannot be construed
133
+ as modifying the License.
134
+
135
+ You may add Your own copyright statement to Your modifications and
136
+ may provide additional or different license terms and conditions
137
+ for use, reproduction, or distribution of Your modifications, or
138
+ for any such Derivative Works as a whole, provided Your use,
139
+ reproduction, and distribution of the Work otherwise complies with
140
+ the conditions stated in this License.
141
+
142
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
143
+ any Contribution intentionally submitted for inclusion in the Work
144
+ by You to the Licensor shall be under the terms and conditions of
145
+ this License, without any additional terms or conditions.
146
+ Notwithstanding the above, nothing herein shall supersede or modify
147
+ the terms of any separate license agreement you may have executed
148
+ with Licensor regarding such Contributions.
149
+
150
+ 6. Trademarks. This License does not grant permission to use the trade
151
+ names, trademarks, service marks, or product names of the Licensor,
152
+ except as required for reasonable and customary use in describing the
153
+ origin of the Work and reproducing the content of the NOTICE file.
154
+
155
+ 7. Disclaimer of Warranty. Unless required by applicable law or
156
+ agreed to in writing, Licensor provides the Work (and each
157
+ Contributor provides its Contributions) on an "AS IS" BASIS,
158
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
159
+ implied, including, without limitation, any warranties or conditions
160
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
161
+ PARTICULAR PURPOSE. You are solely responsible for determining the
162
+ appropriateness of using or redistributing the Work and assume any
163
+ risks associated with Your exercise of permissions under this License.
164
+
165
+ 8. Limitation of Liability. In no event and under no legal theory,
166
+ whether in tort (including negligence), contract, or otherwise,
167
+ unless required by applicable law (such as deliberate and grossly
168
+ negligent acts) or agreed to in writing, shall any Contributor be
169
+ liable to You for damages, including any direct, indirect, special,
170
+ incidental, or consequential damages of any character arising as a
171
+ result of this License or out of the use or inability to use the
172
+ Work (including but not limited to damages for loss of goodwill,
173
+ work stoppage, computer failure or malfunction, or any and all
174
+ other commercial damages or losses), even if such Contributor
175
+ has been advised of the possibility of such damages.
176
+
177
+ 9. Accepting Warranty or Additional Liability. While redistributing
178
+ the Work or Derivative Works thereof, You may choose to offer,
179
+ and charge a fee for, acceptance of support, warranty, indemnity,
180
+ or other liability obligations and/or rights consistent with this
181
+ License. However, in accepting such obligations, You may act only
182
+ on Your own behalf and on Your sole responsibility, not on behalf
183
+ of any other Contributor, and only if You agree to indemnify,
184
+ defend, and hold each Contributor harmless for any liability
185
+ incurred by, or claims asserted against, such Contributor by reason
186
+ of your accepting any such warranty or additional liability.
187
+
188
+ END OF TERMS AND CONDITIONS
189
+
190
+ APPENDIX: How to apply the Apache License to your work.
191
+
192
+ To apply the Apache License to your work, attach the following
193
+ boilerplate notice, with the fields enclosed by brackets "[]"
194
+ replaced with your own identifying information. (Don't include
195
+ the brackets!) The text should be enclosed in the appropriate
196
+ comment syntax for the file format. Please also get an approval
197
+ from your corporate counsel to determine if a copyright notice
198
+ is needed.
199
+
200
+ Copyright [yyyy] [name of copyright owner]
201
+
202
+ Licensed under the Apache License, Version 2.0 (the "License");
203
+ you may not use this file except in compliance with the License.
204
+ You may obtain a copy of the License at
205
+
206
+ http://www.apache.org/licenses/LICENSE-2.0
207
+
208
+ Unless required by applicable law or agreed to in writing, software
209
+ distributed under the License is distributed on an "AS IS" BASIS,
210
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
211
+ implied. See the License for the specific language governing
212
+ permissions and limitations under the License.
package/dist/agent.d.ts CHANGED
@@ -4,8 +4,23 @@ import { type SpinnerStats } from './output.js';
4
4
  import type { BernardConfig } from './config.js';
5
5
  import type { MemoryStore } from './memory.js';
6
6
  import type { RAGStore, RAGSearchResult } from './rag.js';
7
- /** @internal */
8
- export declare function buildSystemPrompt(config: BernardConfig, memoryStore: MemoryStore, mcpServerNames?: string[], ragResults?: RAGSearchResult[]): string;
7
+ import { RoutineStore, type RoutineSummary } from './routines.js';
8
+ /**
9
+ * Assembles the full system prompt including base instructions, memory context, and MCP status.
10
+ * @internal Exported for testing only.
11
+ * @param config - Active Bernard configuration (provider, model, etc.)
12
+ * @param memoryStore - Store used to inject persistent memory and scratch context
13
+ * @param mcpServerNames - Names of currently connected MCP servers, if any
14
+ * @param ragResults - RAG search results to include as recalled context
15
+ * @param routineSummaries - Routine summaries to list in the prompt
16
+ */
17
+ export declare function buildSystemPrompt(config: BernardConfig, memoryStore: MemoryStore, mcpServerNames?: string[], ragResults?: RAGSearchResult[], routineSummaries?: RoutineSummary[]): string;
18
+ /**
19
+ * Core agent that manages a multi-step conversation loop with tool calling via the Vercel AI SDK.
20
+ *
21
+ * Maintains conversation history, handles context compression when token limits
22
+ * approach, performs RAG lookups, and orchestrates LLM calls with registered tools.
23
+ */
9
24
  export declare class Agent {
10
25
  private history;
11
26
  private config;
@@ -21,11 +36,25 @@ export declare class Agent {
21
36
  private lastPromptTokens;
22
37
  private lastStepPromptTokens;
23
38
  private spinnerStats;
24
- constructor(config: BernardConfig, toolOptions: ToolOptions, memoryStore: MemoryStore, mcpTools?: Record<string, any>, mcpServerNames?: string[], alertContext?: string, initialHistory?: CoreMessage[], ragStore?: RAGStore);
39
+ private routineStore;
40
+ constructor(config: BernardConfig, toolOptions: ToolOptions, memoryStore: MemoryStore, mcpTools?: Record<string, any>, mcpServerNames?: string[], alertContext?: string, initialHistory?: CoreMessage[], ragStore?: RAGStore, routineStore?: RoutineStore);
41
+ /** Returns the current conversation message history. */
25
42
  getHistory(): CoreMessage[];
43
+ /** Returns the RAG search results from the most recent `processInput` call. */
26
44
  getLastRAGResults(): RAGSearchResult[];
45
+ /** Cancels the in-flight LLM request, if any. Safe to call when no request is active. */
27
46
  abort(): void;
47
+ /** Attaches a spinner stats object that will be updated with token usage during generation. */
28
48
  setSpinnerStats(stats: SpinnerStats): void;
49
+ /**
50
+ * Sends user input through the agent loop: RAG retrieval, context compression, LLM generation, and tool execution.
51
+ *
52
+ * Appends the user message and all response messages (including tool calls) to the conversation history.
53
+ * Automatically retries with emergency truncation on token overflow errors.
54
+ * @param userInput - The raw text from the user's REPL input
55
+ * @throws Error wrapping the underlying API error if generation fails for non-abort, non-overflow reasons
56
+ */
29
57
  processInput(userInput: string): Promise<void>;
58
+ /** Resets conversation history, scratch notes, and RAG tracking state for a fresh session. */
30
59
  clearHistory(): void;
31
60
  }