pretticlaw 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 (158) hide show
  1. package/CONTRIBUTING.md +123 -0
  2. package/README.md +150 -0
  3. package/assets/logo.png +0 -0
  4. package/dist/agent/context.d.ts +22 -0
  5. package/dist/agent/context.js +85 -0
  6. package/dist/agent/loop.d.ts +63 -0
  7. package/dist/agent/loop.js +244 -0
  8. package/dist/agent/memory.d.ts +16 -0
  9. package/dist/agent/memory.js +98 -0
  10. package/dist/agent/skills.d.ts +18 -0
  11. package/dist/agent/skills.js +121 -0
  12. package/dist/agent/subagent.d.ts +30 -0
  13. package/dist/agent/subagent.js +92 -0
  14. package/dist/agent/tools/base.d.ts +10 -0
  15. package/dist/agent/tools/base.js +58 -0
  16. package/dist/agent/tools/cron.d.ts +43 -0
  17. package/dist/agent/tools/cron.js +83 -0
  18. package/dist/agent/tools/filesystem.d.ts +79 -0
  19. package/dist/agent/tools/filesystem.js +125 -0
  20. package/dist/agent/tools/message.d.ts +41 -0
  21. package/dist/agent/tools/message.js +55 -0
  22. package/dist/agent/tools/registry.d.ts +9 -0
  23. package/dist/agent/tools/registry.js +33 -0
  24. package/dist/agent/tools/shell.d.ts +26 -0
  25. package/dist/agent/tools/shell.js +78 -0
  26. package/dist/agent/tools/spawn.d.ts +27 -0
  27. package/dist/agent/tools/spawn.js +35 -0
  28. package/dist/agent/tools/web.d.ts +50 -0
  29. package/dist/agent/tools/web.js +119 -0
  30. package/dist/bus/async-queue.d.ts +7 -0
  31. package/dist/bus/async-queue.js +20 -0
  32. package/dist/bus/events.d.ts +19 -0
  33. package/dist/bus/events.js +3 -0
  34. package/dist/bus/queue.d.ts +12 -0
  35. package/dist/bus/queue.js +23 -0
  36. package/dist/channels/base.d.ts +22 -0
  37. package/dist/channels/base.js +35 -0
  38. package/dist/channels/discord.d.ts +24 -0
  39. package/dist/channels/discord.js +133 -0
  40. package/dist/channels/manager.d.ts +17 -0
  41. package/dist/channels/manager.js +67 -0
  42. package/dist/channels/stub.d.ts +10 -0
  43. package/dist/channels/stub.js +18 -0
  44. package/dist/channels/telegram.d.ts +20 -0
  45. package/dist/channels/telegram.js +93 -0
  46. package/dist/cli/commands.d.ts +2 -0
  47. package/dist/cli/commands.js +552 -0
  48. package/dist/config/loader.d.ts +5 -0
  49. package/dist/config/loader.js +55 -0
  50. package/dist/config/schema.d.ts +246 -0
  51. package/dist/config/schema.js +94 -0
  52. package/dist/cron/service.d.ts +33 -0
  53. package/dist/cron/service.js +195 -0
  54. package/dist/cron/types.d.ts +47 -0
  55. package/dist/cron/types.js +1 -0
  56. package/dist/dashboard/index.html +1567 -0
  57. package/dist/heartbeat/service.d.ts +21 -0
  58. package/dist/heartbeat/service.js +101 -0
  59. package/dist/index.d.ts +2 -0
  60. package/dist/index.js +5 -0
  61. package/dist/providers/base.d.ts +23 -0
  62. package/dist/providers/base.js +21 -0
  63. package/dist/providers/custom-provider.d.ts +16 -0
  64. package/dist/providers/custom-provider.js +49 -0
  65. package/dist/providers/litellm-provider.d.ts +19 -0
  66. package/dist/providers/litellm-provider.js +128 -0
  67. package/dist/providers/registry.d.ts +5 -0
  68. package/dist/providers/registry.js +45 -0
  69. package/dist/session/manager.d.ts +31 -0
  70. package/dist/session/manager.js +116 -0
  71. package/dist/skills/README.md +25 -0
  72. package/dist/skills/clawhub/SKILL.md +53 -0
  73. package/dist/skills/cron/SKILL.md +57 -0
  74. package/dist/skills/github/SKILL.md +48 -0
  75. package/dist/skills/memory/SKILL.md +31 -0
  76. package/dist/skills/skill-creator/SKILL.md +371 -0
  77. package/dist/skills/summarize/SKILL.md +67 -0
  78. package/dist/skills/tmux/SKILL.md +121 -0
  79. package/dist/skills/tmux/scripts/find-sessions.sh +112 -0
  80. package/dist/skills/tmux/scripts/wait-for-text.sh +83 -0
  81. package/dist/skills/weather/SKILL.md +49 -0
  82. package/dist/templates/AGENTS.md +23 -0
  83. package/dist/templates/HEARTBEAT.md +16 -0
  84. package/dist/templates/SOUL.md +21 -0
  85. package/dist/templates/TOOLS.md +15 -0
  86. package/dist/templates/USER.md +49 -0
  87. package/dist/templates/memory/MEMORY.md +23 -0
  88. package/dist/types.d.ts +4 -0
  89. package/dist/types.js +3 -0
  90. package/dist/utils/helpers.d.ts +5 -0
  91. package/dist/utils/helpers.js +53 -0
  92. package/dist/web/server.d.ts +15 -0
  93. package/dist/web/server.js +169 -0
  94. package/package.json +37 -0
  95. package/scripts/copy-assets.mjs +21 -0
  96. package/src/agent/context.ts +90 -0
  97. package/src/agent/loop.ts +291 -0
  98. package/src/agent/memory.ts +104 -0
  99. package/src/agent/skills.ts +121 -0
  100. package/src/agent/subagent.ts +96 -0
  101. package/src/agent/tools/base.ts +59 -0
  102. package/src/agent/tools/cron.ts +79 -0
  103. package/src/agent/tools/filesystem.ts +93 -0
  104. package/src/agent/tools/message.ts +57 -0
  105. package/src/agent/tools/registry.ts +36 -0
  106. package/src/agent/tools/shell.ts +69 -0
  107. package/src/agent/tools/spawn.ts +37 -0
  108. package/src/agent/tools/web.ts +108 -0
  109. package/src/bus/async-queue.ts +20 -0
  110. package/src/bus/events.ts +23 -0
  111. package/src/bus/queue.ts +31 -0
  112. package/src/channels/base.ts +36 -0
  113. package/src/channels/discord.ts +156 -0
  114. package/src/channels/manager.ts +70 -0
  115. package/src/channels/stub.ts +20 -0
  116. package/src/channels/telegram.ts +120 -0
  117. package/src/cli/commands.ts +581 -0
  118. package/src/config/loader.ts +58 -0
  119. package/src/config/schema.ts +144 -0
  120. package/src/cron/service.ts +190 -0
  121. package/src/cron/types.ts +36 -0
  122. package/src/dashboard/index.html +1567 -0
  123. package/src/heartbeat/service.ts +95 -0
  124. package/src/index.ts +6 -0
  125. package/src/providers/base.ts +43 -0
  126. package/src/providers/custom-provider.ts +46 -0
  127. package/src/providers/litellm-provider.ts +131 -0
  128. package/src/providers/registry.ts +48 -0
  129. package/src/session/manager.ts +129 -0
  130. package/src/skills/README.md +25 -0
  131. package/src/skills/clawhub/SKILL.md +53 -0
  132. package/src/skills/cron/SKILL.md +57 -0
  133. package/src/skills/github/SKILL.md +48 -0
  134. package/src/skills/memory/SKILL.md +31 -0
  135. package/src/skills/skill-creator/SKILL.md +371 -0
  136. package/src/skills/summarize/SKILL.md +67 -0
  137. package/src/skills/tmux/SKILL.md +121 -0
  138. package/src/skills/tmux/scripts/find-sessions.sh +112 -0
  139. package/src/skills/tmux/scripts/wait-for-text.sh +83 -0
  140. package/src/skills/weather/SKILL.md +49 -0
  141. package/src/templates/AGENTS.md +23 -0
  142. package/src/templates/HEARTBEAT.md +16 -0
  143. package/src/templates/SOUL.md +21 -0
  144. package/src/templates/TOOLS.md +15 -0
  145. package/src/templates/USER.md +49 -0
  146. package/src/templates/memory/MEMORY.md +23 -0
  147. package/src/types/prompts.d.ts +14 -0
  148. package/src/types/ws.d.ts +15 -0
  149. package/src/types.ts +5 -0
  150. package/src/utils/helpers.ts +55 -0
  151. package/src/web/server.ts +198 -0
  152. package/test/context.test.ts +27 -0
  153. package/test/cron-service.test.ts +31 -0
  154. package/test/message-tool.test.ts +10 -0
  155. package/test/providers.test.ts +43 -0
  156. package/test/tool-validation.test.ts +61 -0
  157. package/tsconfig.json +16 -0
  158. package/vitest.config.ts +8 -0
@@ -0,0 +1,123 @@
1
+ # Contributing to Pretticlaw
2
+
3
+ Thank you for your interest in contributing to **Pretticlaw**! We welcome contributions from everyone.
4
+
5
+ ## Getting Started
6
+
7
+ 1. **Fork** the repository on [GitHub](https://github.com/prettiflow/pretticlaw).
8
+ 2. **Clone** your fork locally:
9
+ ```bash
10
+ git clone https://github.com/<your-username>/pretticlaw.git
11
+ cd pretticlaw
12
+ ```
13
+ 3. **Install dependencies**:
14
+ ```bash
15
+ npm install
16
+ ```
17
+ 4. **Build** the project:
18
+ ```bash
19
+ npm run build
20
+ ```
21
+ 5. **Link** for local testing:
22
+ ```bash
23
+ npm link
24
+ ```
25
+
26
+ ## Development Workflow
27
+
28
+ 1. Create a new branch from `main`:
29
+ ```bash
30
+ git checkout -b feat/my-feature
31
+ ```
32
+ 2. Make your changes.
33
+ 3. Run the build to verify everything compiles:
34
+ ```bash
35
+ npm run build
36
+ ```
37
+ 4. Run tests:
38
+ ```bash
39
+ npm test
40
+ ```
41
+ 5. Commit your changes with a clear message:
42
+ ```bash
43
+ git commit -m "feat: add support for new provider"
44
+ ```
45
+ 6. Push and open a Pull Request against `main`.
46
+
47
+ ## Commit Convention
48
+
49
+ We use conventional commits:
50
+
51
+ | Prefix | Usage |
52
+ |---|---|
53
+ | `feat:` | New feature |
54
+ | `fix:` | Bug fix |
55
+ | `docs:` | Documentation only |
56
+ | `refactor:` | Code change that neither fixes a bug nor adds a feature |
57
+ | `test:` | Adding or updating tests |
58
+ | `chore:` | Tooling, CI, or dependency updates |
59
+
60
+ ## Project Structure
61
+
62
+ ```
63
+ src/
64
+ ├── agent/ # Agent loop, context, memory, skills, tools
65
+ ├── bus/ # Event bus and async queue
66
+ ├── channels/ # Discord, Telegram, stub channels
67
+ ├── cli/ # CLI commands
68
+ ├── config/ # Config loader and schema
69
+ ├── cron/ # Cron service and types
70
+ ├── dashboard/ # Dashboard HTML assets
71
+ ├── heartbeat/ # Heartbeat service
72
+ ├── providers/ # LLM providers (OpenAI, Anthropic, Groq, OpenRouter, custom)
73
+ ├── session/ # Session manager
74
+ ├── skills/ # Built-in skills (cron, github, memory, weather, etc.)
75
+ ├── templates/ # Agent prompt templates
76
+ ├── utils/ # Helpers
77
+ └── web/ # Web server for dashboard
78
+ ```
79
+
80
+ ## Adding a New Provider
81
+
82
+ 1. Create a new file in `src/providers/` (e.g., `my-provider.ts`).
83
+ 2. Extend `BaseProvider` from `src/providers/base.ts`.
84
+ 3. Register it in `src/providers/registry.ts`.
85
+ 4. Add any config schema changes to `src/config/schema.ts`.
86
+
87
+ ## Adding a New Tool
88
+
89
+ 1. Create a new file in `src/agent/tools/` (e.g., `my-tool.ts`).
90
+ 2. Extend `BaseTool` from `src/agent/tools/base.ts`.
91
+ 3. Register it in `src/agent/tools/registry.ts`.
92
+
93
+ ## Adding a New Skill
94
+
95
+ 1. Create a new directory under `src/skills/` (e.g., `src/skills/my-skill/`).
96
+ 2. Add a `SKILL.md` file describing the skill.
97
+ 3. The skill will be auto-discovered at runtime.
98
+
99
+ ## Code Style
100
+
101
+ - **TypeScript** — all source code lives in `src/` and compiles to `dist/`.
102
+ - Follow existing patterns and conventions in the codebase.
103
+ - Keep functions small and focused.
104
+ - Prefer explicit types over `any`.
105
+
106
+ ## Reporting Issues
107
+
108
+ Please [open an issue](https://github.com/prettiflow/pretticlaw/issues) with:
109
+ - A clear description of the problem.
110
+ - Steps to reproduce.
111
+ - Expected vs. actual behavior.
112
+ - Your environment (OS, Node version, Pretticlaw version).
113
+
114
+ ## Links
115
+
116
+ - [Prettiflow](https://prettiflow.tech) — our main platform
117
+ - [Pretticlaw](https://prettiflow.tech/claw) — this project
118
+
119
+ ---
120
+
121
+ <div align="center">
122
+ <sub>Built with ❤️ by the <a href="https://prettiflow.tech">Prettiflow</a> team</sub>
123
+ </div>
package/README.md ADDED
@@ -0,0 +1,150 @@
1
+ <div align="center">
2
+ <img src="/assets/logo.png" alt="Pretticlaw" width="320">
3
+ <h1>Pretticlaw</h1>
4
+ <p><strong>Lightweight AI Assistant That Lives in Your Computer.</strong></p>
5
+ <p>Inspired by <a href="https://openclaw.ai">OpenClaw</a>.</p>
6
+ <p>
7
+ <a href="https://prettiflow.tech/claw"><strong>prettiflow.tech/claw</strong></a>
8
+ · <a href="https://prettiflow.tech">prettiflow.tech</a>
9
+ · <a href="https://openclaw.ai">openclaw.ai</a>
10
+ · <a href="https://github.com/prettiflow/pretticlaw/blob/main/LICENSE">MIT</a>
11
+ </p>
12
+ </div>
13
+
14
+ ---
15
+
16
+ ## What is Pretticlaw?
17
+
18
+ Pretticlaw is a **minimal yet full-featured** agent platform that ships with:
19
+
20
+ - Zero boilerplate CLI: `pretticlaw agent`, `pretticlaw gateway`, `pretticlaw doctor`.
21
+ - A **rich browser dashboard** on port 6767 with tabs for chat, channels, cron, settings, and status.
22
+ - Tool-call aware chat + spinner/hover cues + live channel/cron wiring.
23
+ - Multi-provider support: <a href="https://platform.openai.com">OpenAI</a>, <a href="https://docs.anthropic.com">Anthropic</a>, <a href="https://console.groq.com">Groq</a>, <a href="https://openrouter.ai">OpenRouter</a>, and more, all tuned for tool-call support.
24
+
25
+ Part of the <a href="https://prettiflow.tech">Prettiflow</a> ecosystem, the first infrastructure for AI-built software.
26
+
27
+ ## Use Cases
28
+
29
+ ### 📈 Around-the-Clock Market Intelligence
30
+
31
+ Pretticlaw can monitor stocks, crypto, forex, and commodities in real time, delivering automated alerts, trend summaries, and portfolio snapshots while you sleep. Set up a cron job and wake up to a full market briefing every morning.
32
+
33
+ ### 🚀 Your Software Engineer Intern
34
+
35
+ Need a REST API scaffolded, a React dashboard wired up, or a database migration written? Pretticlaw reads your codebase, writes production-grade code, runs shell commands, and iterates on bugs, acting as a full-stack engineer that never clocks out.
36
+
37
+ ### 📅 Intelligent Daily Planner
38
+
39
+ From scheduling meetings to sending reminders and organizing your to-do list, Pretticlaw manages your daily workflow. It learns your habits through memory, prioritizes tasks, and keeps your routine on track with scheduled heartbeat check-ins.
40
+
41
+ ### 📚 Personal Research and Knowledge Companion
42
+
43
+ Ask Pretticlaw anything: summarize a paper, search the web for the latest docs, compile notes from multiple sources, or maintain a personal knowledge base. It fetches, reads, and distills information so you can focus on what matters.
44
+
45
+ ## Quick Install
46
+
47
+ ```bash
48
+ npm install -g pretticlaw
49
+ pretticlaw onboarding
50
+ pretticlaw gateway # start gateway + dashboard
51
+ pretticlaw agent -m "Hello"
52
+ ```
53
+
54
+ ## Running Locally
55
+
56
+ 1. **Global binary**: `pretticlaw` is published as an npm CLI (call `pretticlaw --help`).
57
+ 2. **Development**: clone the <a href="https://github.com/prettiflow/pretticlaw">repo</a>, run `npm install`, `npm run build`, `npm link` to test changes.
58
+ 3. **Dashboard**: while the gateway runs, visit <a href="http://localhost:6767/chat">`http://localhost:6767/chat`</a> to interact, adjust channels, tweak cron jobs, or inspect status.
59
+
60
+ ## Providers
61
+
62
+ Pretticlaw supports multiple LLM providers out of the box:
63
+
64
+ | Provider | Link | Notes |
65
+ |---|---|---|
66
+ | **OpenAI** | <a href="https://platform.openai.com">platform.openai.com</a> | GPT-4o, GPT-4, GPT-3.5, full tool-call support |
67
+ | **Anthropic** | <a href="https://docs.anthropic.com">docs.anthropic.com</a> | Claude 4, Claude 3.5 Sonnet, tool-use ready |
68
+ | **Groq** | <a href="https://console.groq.com">console.groq.com</a> | GPT-OSS-120B, Llama 4, ultra-fast inference |
69
+ | **OpenRouter** | <a href="https://openrouter.ai">openrouter.ai</a> | Unified access to 200+ models |
70
+ | **Custom** | - | Any OpenAI-compatible endpoint |
71
+
72
+ Configure your provider during `pretticlaw onboarding` or via `~/.pretticlaw/config.json`.
73
+
74
+ ## Channel Onboarding
75
+
76
+ `pretticlaw onboarding` walks you through:
77
+ 1. Provider / model / API key selection.
78
+ 2. Whether you want a chat channel (Telegram / WhatsApp).
79
+ 3. Channel token input, stored directly in `~/.pretticlaw/config.json`.
80
+
81
+ Want to tweak later? Update the dashboard <a href="http://localhost:6767/channels">`/channels`</a> tab or edit `~/.pretticlaw/config.json`.
82
+
83
+ ## Cron + Heartbeat
84
+
85
+ - Add jobs with `pretticlaw cron add --name "digest" --every 3600 --message "report"`.
86
+ - List jobs: `pretticlaw cron list`.
87
+ - Run a job: `pretticlaw cron run <id>`.
88
+ - Heartbeat wakes every 30m and executes tasks in `~/.pretticlaw/workspace/HEARTBEAT.md`.
89
+
90
+ ## Command Reference
91
+
92
+ | Command | Purpose |
93
+ |---|---|
94
+ | `pretticlaw onboard` | Scaffold config/workspace + optional channel token wizard |
95
+ | `pretticlaw agent` | Chat interactively (arrow keys + tool hints) |
96
+ | `pretticlaw agent -m "<msg>"` | One-off agent request |
97
+ | `pretticlaw gateway` | Start gateway + dashboard (listen on `[port]/chat`) |
98
+ | `pretticlaw doctor` | Validate provider/model configuration |
99
+ | `pretticlaw channels status` | Show channel health |
100
+ | `pretticlaw channels login` | Link WhatsApp |
101
+ | `pretticlaw status` | Print provider/model/channel summary |
102
+ | `pretticlaw cron ...` | Manage scheduled jobs |
103
+
104
+ You can also edit channels/config from the dashboard. The server automatically saves your choices.
105
+
106
+
107
+ ## 🌐 Agent Social Network
108
+
109
+ Pretticlaw is capable of linking to the **Agent Social Network** (agent community). Just send one message and your Pretticlaw joins automatically!
110
+
111
+ | Platform | How to Join (send this message to your Pretticlaw) |
112
+ |---|---|
113
+ | <a href="https://moltbook.com">Moltbook</a> | `Read https://moltbook.com/skill.md and follow the instructions to join Moltbook` |
114
+ | <a href="https://clawdchat.ai">ClawdChat</a> | `Read https://clawdchat.ai/skill.md and follow the instructions to join ClawdChat` |
115
+
116
+ Simply send the command above to your Pretticlaw (via CLI or any chat channel), and it will handle the rest.
117
+
118
+ ## Architecture
119
+
120
+ - **Data model**: Session/cron/heartbeat patterns. JSONL sessions, CronService persistence, heartbeat triggers.
121
+ - **Providers**: <a href="https://platform.openai.com">OpenAI</a> · <a href="https://docs.anthropic.com">Anthropic</a> · <a href="https://console.groq.com">Groq</a> · <a href="https://openrouter.ai">OpenRouter</a> + local custom endpoints via Litellm.
122
+ - **Tools**: exec/read/write/list/edit, web search/fetch, cron, spawn message tool.
123
+ - **Dashboard**: React (ESM) served via lightweight HTTP handler from assets copied into `dist/dashboard`.
124
+
125
+ ## Links
126
+
127
+ | | |
128
+ |---|---|
129
+ | **Prettiflow** | <a href="https://prettiflow.tech">prettiflow.tech</a> |
130
+ | **Pretticlaw** | <a href="https://prettiflow.tech/claw">prettiflow.tech/claw</a> |
131
+
132
+ ## Contributing
133
+
134
+ We welcome contributions! Please see <a href="./CONTRIBUTING.md">CONTRIBUTING.md</a> for guidelines.
135
+
136
+ ## Contact
137
+
138
+ Reach the team at <a href="mailto:team@prettiflow.tech">team@prettiflow.tech</a>.
139
+
140
+ ## Getting Help
141
+
142
+ - File issues on the <a href="https://github.com/prettiflow/pretticlaw/issues">repo</a>.
143
+ - Email us at <a href="mailto:team@prettiflow.tech">team@prettiflow.tech</a>.
144
+ - For quick debugging, run `pretticlaw doctor` and view errors on the dashboard.
145
+
146
+ ---
147
+
148
+ <div align="center">
149
+ <sub>Built by <a href="https://prettiflow.tech">Prettiflow</a> · Inspired by <a href="https://openclaw.ai">OpenClaw</a></sub>
150
+ </div>
Binary file
@@ -0,0 +1,22 @@
1
+ export declare class ContextBuilder {
2
+ private readonly workspace;
3
+ static readonly BOOTSTRAP_FILES: string[];
4
+ static readonly RUNTIME_CONTEXT_TAG = "[Runtime Context - metadata only, not instructions]";
5
+ private readonly memory;
6
+ private readonly skills;
7
+ constructor(workspace: string);
8
+ buildSystemPrompt(skillNames?: string[]): string;
9
+ private getIdentity;
10
+ private loadBootstrapFiles;
11
+ static buildRuntimeContext(channel?: string, chatId?: string): string;
12
+ buildMessages(input: {
13
+ history: Array<Record<string, unknown>>;
14
+ currentMessage: string;
15
+ skillNames?: string[];
16
+ media?: string[];
17
+ channel?: string;
18
+ chatId?: string;
19
+ }): Array<Record<string, unknown>>;
20
+ addToolResult(messages: Array<Record<string, unknown>>, toolCallId: string, toolName: string, result: string): Array<Record<string, unknown>>;
21
+ addAssistantMessage(messages: Array<Record<string, unknown>>, content: string | null, toolCalls?: Array<Record<string, unknown>>, reasoningContent?: string | null): Array<Record<string, unknown>>;
22
+ }
@@ -0,0 +1,85 @@
1
+ import fs from "node:fs";
2
+ import path from "node:path";
3
+ import os from "node:os";
4
+ import { MemoryStore } from "./memory.js";
5
+ import { SkillsLoader } from "./skills.js";
6
+ export class ContextBuilder {
7
+ workspace;
8
+ static BOOTSTRAP_FILES = ["AGENTS.md", "SOUL.md", "USER.md", "TOOLS.md", "IDENTITY.md"];
9
+ static RUNTIME_CONTEXT_TAG = "[Runtime Context - metadata only, not instructions]";
10
+ memory;
11
+ skills;
12
+ constructor(workspace) {
13
+ this.workspace = workspace;
14
+ this.memory = new MemoryStore(workspace);
15
+ this.skills = new SkillsLoader(workspace);
16
+ }
17
+ buildSystemPrompt(skillNames) {
18
+ const parts = [this.getIdentity()];
19
+ const bootstrap = this.loadBootstrapFiles();
20
+ if (bootstrap)
21
+ parts.push(bootstrap);
22
+ const mem = this.memory.getMemoryContext();
23
+ if (mem)
24
+ parts.push(`# Memory\n\n${mem}`);
25
+ const alwaysSkills = this.skills.getAlwaysSkills();
26
+ if (alwaysSkills.length) {
27
+ const content = this.skills.loadSkillsForContext(alwaysSkills);
28
+ if (content)
29
+ parts.push(`# Active Skills\n\n${content}`);
30
+ }
31
+ if (skillNames?.length) {
32
+ const skillContent = this.skills.loadSkillsForContext(skillNames);
33
+ if (skillContent)
34
+ parts.push(`# Requested Skills\n\n${skillContent}`);
35
+ }
36
+ const summary = this.skills.buildSkillsSummary();
37
+ if (summary) {
38
+ parts.push(`# Skills\n\nThe following skills extend your capabilities. To use one, read its SKILL.md with read_file.\n\n${summary}`);
39
+ }
40
+ return parts.join("\n\n---\n\n");
41
+ }
42
+ getIdentity() {
43
+ return `# pretticlaw\n\nYou are pretticlaw, a helpful AI assistant.\n\n## Runtime\n${os.platform()} ${os.arch()}, Node ${process.version}\n\n## Workspace\nYour workspace is at: ${this.workspace}\n- Long-term memory: ${path.join(this.workspace, "memory", "MEMORY.md")}\n- History log: ${path.join(this.workspace, "memory", "HISTORY.md")}\n- Custom skills: ${path.join(this.workspace, "skills", "{skill-name}", "SKILL.md")}\n\n## Guidelines\n- State intent before tool calls, but never claim results before receiving them.\n- Before modifying a file, read it first.\n- Ask for clarification when the request is ambiguous.`;
44
+ }
45
+ loadBootstrapFiles() {
46
+ const parts = [];
47
+ for (const f of ContextBuilder.BOOTSTRAP_FILES) {
48
+ const p = path.join(this.workspace, f);
49
+ if (!fs.existsSync(p))
50
+ continue;
51
+ parts.push(`## ${f}\n\n${fs.readFileSync(p, "utf8")}`);
52
+ }
53
+ return parts.join("\n\n");
54
+ }
55
+ static buildRuntimeContext(channel, chatId) {
56
+ const now = new Date();
57
+ const lines = [`Current Time: ${now.toISOString()}`];
58
+ if (channel && chatId) {
59
+ lines.push(`Channel: ${channel}`);
60
+ lines.push(`Chat ID: ${chatId}`);
61
+ }
62
+ return `${ContextBuilder.RUNTIME_CONTEXT_TAG}\n${lines.join("\n")}`;
63
+ }
64
+ buildMessages(input) {
65
+ return [
66
+ { role: "system", content: this.buildSystemPrompt(input.skillNames) },
67
+ ...input.history,
68
+ { role: "user", content: ContextBuilder.buildRuntimeContext(input.channel, input.chatId) },
69
+ { role: "user", content: input.currentMessage },
70
+ ];
71
+ }
72
+ addToolResult(messages, toolCallId, toolName, result) {
73
+ messages.push({ role: "tool", tool_call_id: toolCallId, name: toolName, content: result });
74
+ return messages;
75
+ }
76
+ addAssistantMessage(messages, content, toolCalls, reasoningContent) {
77
+ const msg = { role: "assistant", content };
78
+ if (toolCalls?.length)
79
+ msg.tool_calls = toolCalls;
80
+ if (reasoningContent != null)
81
+ msg.reasoning_content = reasoningContent;
82
+ messages.push(msg);
83
+ return messages;
84
+ }
85
+ }
@@ -0,0 +1,63 @@
1
+ import { SubagentManager } from "./subagent.js";
2
+ import { ToolRegistry } from "./tools/registry.js";
3
+ import type { MessageBus } from "../bus/queue.js";
4
+ import type { InboundMessage, OutboundMessage } from "../bus/events.js";
5
+ import type { LLMProvider } from "../providers/base.js";
6
+ import { SessionManager } from "../session/manager.js";
7
+ import type { CronService } from "../cron/service.js";
8
+ type ProgressFn = (content: string, meta?: {
9
+ toolHint?: boolean;
10
+ tool_calls?: any[];
11
+ }) => Promise<void>;
12
+ export declare class AgentLoop {
13
+ private readonly input;
14
+ private readonly context;
15
+ private readonly sessions;
16
+ readonly tools: ToolRegistry;
17
+ readonly subagents: SubagentManager;
18
+ private running;
19
+ private readonly consolidating;
20
+ private readonly activeTasks;
21
+ private processing;
22
+ private static readonly TOOL_RESULT_MAX_CHARS;
23
+ constructor(input: {
24
+ bus: MessageBus;
25
+ provider: LLMProvider;
26
+ workspace: string;
27
+ model?: string;
28
+ maxIterations?: number;
29
+ temperature?: number;
30
+ maxTokens?: number;
31
+ memoryWindow?: number;
32
+ braveApiKey?: string | null;
33
+ execConfig?: {
34
+ timeout: number;
35
+ pathAppend: string;
36
+ };
37
+ cronService?: CronService;
38
+ restrictToWorkspace?: boolean;
39
+ sessionManager?: SessionManager;
40
+ channelsConfig?: {
41
+ sendProgress: boolean;
42
+ sendToolHints: boolean;
43
+ };
44
+ });
45
+ get model(): string;
46
+ get channelsConfig(): {
47
+ sendProgress: boolean;
48
+ sendToolHints: boolean;
49
+ } | undefined;
50
+ private registerDefaultTools;
51
+ private setToolContext;
52
+ private toolHint;
53
+ private runAgentLoop;
54
+ run(): Promise<void>;
55
+ stop(): void;
56
+ processDirect(content: string, session?: string, channel?: string, chatId?: string, onProgress?: ProgressFn): Promise<string>;
57
+ private dispatch;
58
+ private handleStop;
59
+ private consolidateMemory;
60
+ private saveTurn;
61
+ processMessage(msg: InboundMessage, sessionKeyOverride?: string, onProgress?: ProgressFn): Promise<OutboundMessage | null>;
62
+ }
63
+ export {};