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.
- package/CONTRIBUTING.md +123 -0
- package/README.md +150 -0
- package/assets/logo.png +0 -0
- package/dist/agent/context.d.ts +22 -0
- package/dist/agent/context.js +85 -0
- package/dist/agent/loop.d.ts +63 -0
- package/dist/agent/loop.js +244 -0
- package/dist/agent/memory.d.ts +16 -0
- package/dist/agent/memory.js +98 -0
- package/dist/agent/skills.d.ts +18 -0
- package/dist/agent/skills.js +121 -0
- package/dist/agent/subagent.d.ts +30 -0
- package/dist/agent/subagent.js +92 -0
- package/dist/agent/tools/base.d.ts +10 -0
- package/dist/agent/tools/base.js +58 -0
- package/dist/agent/tools/cron.d.ts +43 -0
- package/dist/agent/tools/cron.js +83 -0
- package/dist/agent/tools/filesystem.d.ts +79 -0
- package/dist/agent/tools/filesystem.js +125 -0
- package/dist/agent/tools/message.d.ts +41 -0
- package/dist/agent/tools/message.js +55 -0
- package/dist/agent/tools/registry.d.ts +9 -0
- package/dist/agent/tools/registry.js +33 -0
- package/dist/agent/tools/shell.d.ts +26 -0
- package/dist/agent/tools/shell.js +78 -0
- package/dist/agent/tools/spawn.d.ts +27 -0
- package/dist/agent/tools/spawn.js +35 -0
- package/dist/agent/tools/web.d.ts +50 -0
- package/dist/agent/tools/web.js +119 -0
- package/dist/bus/async-queue.d.ts +7 -0
- package/dist/bus/async-queue.js +20 -0
- package/dist/bus/events.d.ts +19 -0
- package/dist/bus/events.js +3 -0
- package/dist/bus/queue.d.ts +12 -0
- package/dist/bus/queue.js +23 -0
- package/dist/channels/base.d.ts +22 -0
- package/dist/channels/base.js +35 -0
- package/dist/channels/discord.d.ts +24 -0
- package/dist/channels/discord.js +133 -0
- package/dist/channels/manager.d.ts +17 -0
- package/dist/channels/manager.js +67 -0
- package/dist/channels/stub.d.ts +10 -0
- package/dist/channels/stub.js +18 -0
- package/dist/channels/telegram.d.ts +20 -0
- package/dist/channels/telegram.js +93 -0
- package/dist/cli/commands.d.ts +2 -0
- package/dist/cli/commands.js +552 -0
- package/dist/config/loader.d.ts +5 -0
- package/dist/config/loader.js +55 -0
- package/dist/config/schema.d.ts +246 -0
- package/dist/config/schema.js +94 -0
- package/dist/cron/service.d.ts +33 -0
- package/dist/cron/service.js +195 -0
- package/dist/cron/types.d.ts +47 -0
- package/dist/cron/types.js +1 -0
- package/dist/dashboard/index.html +1567 -0
- package/dist/heartbeat/service.d.ts +21 -0
- package/dist/heartbeat/service.js +101 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +5 -0
- package/dist/providers/base.d.ts +23 -0
- package/dist/providers/base.js +21 -0
- package/dist/providers/custom-provider.d.ts +16 -0
- package/dist/providers/custom-provider.js +49 -0
- package/dist/providers/litellm-provider.d.ts +19 -0
- package/dist/providers/litellm-provider.js +128 -0
- package/dist/providers/registry.d.ts +5 -0
- package/dist/providers/registry.js +45 -0
- package/dist/session/manager.d.ts +31 -0
- package/dist/session/manager.js +116 -0
- package/dist/skills/README.md +25 -0
- package/dist/skills/clawhub/SKILL.md +53 -0
- package/dist/skills/cron/SKILL.md +57 -0
- package/dist/skills/github/SKILL.md +48 -0
- package/dist/skills/memory/SKILL.md +31 -0
- package/dist/skills/skill-creator/SKILL.md +371 -0
- package/dist/skills/summarize/SKILL.md +67 -0
- package/dist/skills/tmux/SKILL.md +121 -0
- package/dist/skills/tmux/scripts/find-sessions.sh +112 -0
- package/dist/skills/tmux/scripts/wait-for-text.sh +83 -0
- package/dist/skills/weather/SKILL.md +49 -0
- package/dist/templates/AGENTS.md +23 -0
- package/dist/templates/HEARTBEAT.md +16 -0
- package/dist/templates/SOUL.md +21 -0
- package/dist/templates/TOOLS.md +15 -0
- package/dist/templates/USER.md +49 -0
- package/dist/templates/memory/MEMORY.md +23 -0
- package/dist/types.d.ts +4 -0
- package/dist/types.js +3 -0
- package/dist/utils/helpers.d.ts +5 -0
- package/dist/utils/helpers.js +53 -0
- package/dist/web/server.d.ts +15 -0
- package/dist/web/server.js +169 -0
- package/package.json +37 -0
- package/scripts/copy-assets.mjs +21 -0
- package/src/agent/context.ts +90 -0
- package/src/agent/loop.ts +291 -0
- package/src/agent/memory.ts +104 -0
- package/src/agent/skills.ts +121 -0
- package/src/agent/subagent.ts +96 -0
- package/src/agent/tools/base.ts +59 -0
- package/src/agent/tools/cron.ts +79 -0
- package/src/agent/tools/filesystem.ts +93 -0
- package/src/agent/tools/message.ts +57 -0
- package/src/agent/tools/registry.ts +36 -0
- package/src/agent/tools/shell.ts +69 -0
- package/src/agent/tools/spawn.ts +37 -0
- package/src/agent/tools/web.ts +108 -0
- package/src/bus/async-queue.ts +20 -0
- package/src/bus/events.ts +23 -0
- package/src/bus/queue.ts +31 -0
- package/src/channels/base.ts +36 -0
- package/src/channels/discord.ts +156 -0
- package/src/channels/manager.ts +70 -0
- package/src/channels/stub.ts +20 -0
- package/src/channels/telegram.ts +120 -0
- package/src/cli/commands.ts +581 -0
- package/src/config/loader.ts +58 -0
- package/src/config/schema.ts +144 -0
- package/src/cron/service.ts +190 -0
- package/src/cron/types.ts +36 -0
- package/src/dashboard/index.html +1567 -0
- package/src/heartbeat/service.ts +95 -0
- package/src/index.ts +6 -0
- package/src/providers/base.ts +43 -0
- package/src/providers/custom-provider.ts +46 -0
- package/src/providers/litellm-provider.ts +131 -0
- package/src/providers/registry.ts +48 -0
- package/src/session/manager.ts +129 -0
- package/src/skills/README.md +25 -0
- package/src/skills/clawhub/SKILL.md +53 -0
- package/src/skills/cron/SKILL.md +57 -0
- package/src/skills/github/SKILL.md +48 -0
- package/src/skills/memory/SKILL.md +31 -0
- package/src/skills/skill-creator/SKILL.md +371 -0
- package/src/skills/summarize/SKILL.md +67 -0
- package/src/skills/tmux/SKILL.md +121 -0
- package/src/skills/tmux/scripts/find-sessions.sh +112 -0
- package/src/skills/tmux/scripts/wait-for-text.sh +83 -0
- package/src/skills/weather/SKILL.md +49 -0
- package/src/templates/AGENTS.md +23 -0
- package/src/templates/HEARTBEAT.md +16 -0
- package/src/templates/SOUL.md +21 -0
- package/src/templates/TOOLS.md +15 -0
- package/src/templates/USER.md +49 -0
- package/src/templates/memory/MEMORY.md +23 -0
- package/src/types/prompts.d.ts +14 -0
- package/src/types/ws.d.ts +15 -0
- package/src/types.ts +5 -0
- package/src/utils/helpers.ts +55 -0
- package/src/web/server.ts +198 -0
- package/test/context.test.ts +27 -0
- package/test/cron-service.test.ts +31 -0
- package/test/message-tool.test.ts +10 -0
- package/test/providers.test.ts +43 -0
- package/test/tool-validation.test.ts +61 -0
- package/tsconfig.json +16 -0
- package/vitest.config.ts +8 -0
package/CONTRIBUTING.md
ADDED
|
@@ -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>
|
package/assets/logo.png
ADDED
|
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 {};
|