notsleep 1.0.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/.env.example +117 -0
- package/LICENSE +21 -0
- package/README.md +341 -0
- package/dashboard/index.html +893 -0
- package/dist/agent.d.ts +162 -0
- package/dist/agent.d.ts.map +1 -0
- package/dist/agent.js +1064 -0
- package/dist/agent.js.map +1 -0
- package/dist/api.d.ts +10 -0
- package/dist/api.d.ts.map +1 -0
- package/dist/api.js +39 -0
- package/dist/api.js.map +1 -0
- package/dist/checkpoint.d.ts +52 -0
- package/dist/checkpoint.d.ts.map +1 -0
- package/dist/checkpoint.js +234 -0
- package/dist/checkpoint.js.map +1 -0
- package/dist/config.d.ts +24 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +265 -0
- package/dist/config.js.map +1 -0
- package/dist/context.d.ts +15 -0
- package/dist/context.d.ts.map +1 -0
- package/dist/context.js +237 -0
- package/dist/context.js.map +1 -0
- package/dist/cost.d.ts +26 -0
- package/dist/cost.d.ts.map +1 -0
- package/dist/cost.js +161 -0
- package/dist/cost.js.map +1 -0
- package/dist/dashboard.d.ts +96 -0
- package/dist/dashboard.d.ts.map +1 -0
- package/dist/dashboard.js +292 -0
- package/dist/dashboard.js.map +1 -0
- package/dist/fileconfig.d.ts +129 -0
- package/dist/fileconfig.d.ts.map +1 -0
- package/dist/fileconfig.js +391 -0
- package/dist/fileconfig.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +882 -0
- package/dist/index.js.map +1 -0
- package/dist/init.d.ts +9 -0
- package/dist/init.d.ts.map +1 -0
- package/dist/init.js +221 -0
- package/dist/init.js.map +1 -0
- package/dist/logger.d.ts +33 -0
- package/dist/logger.d.ts.map +1 -0
- package/dist/logger.js +150 -0
- package/dist/logger.js.map +1 -0
- package/dist/modelsdev.d.ts +63 -0
- package/dist/modelsdev.d.ts.map +1 -0
- package/dist/modelsdev.js +265 -0
- package/dist/modelsdev.js.map +1 -0
- package/dist/parallel.d.ts +54 -0
- package/dist/parallel.d.ts.map +1 -0
- package/dist/parallel.js +139 -0
- package/dist/parallel.js.map +1 -0
- package/dist/pool.d.ts +17 -0
- package/dist/pool.d.ts.map +1 -0
- package/dist/pool.js +53 -0
- package/dist/pool.js.map +1 -0
- package/dist/provider.d.ts +60 -0
- package/dist/provider.d.ts.map +1 -0
- package/dist/provider.js +396 -0
- package/dist/provider.js.map +1 -0
- package/dist/registry.d.ts +60 -0
- package/dist/registry.d.ts.map +1 -0
- package/dist/registry.js +153 -0
- package/dist/registry.js.map +1 -0
- package/dist/safety.d.ts +21 -0
- package/dist/safety.d.ts.map +1 -0
- package/dist/safety.js +118 -0
- package/dist/safety.js.map +1 -0
- package/dist/schema.d.ts +9 -0
- package/dist/schema.d.ts.map +1 -0
- package/dist/schema.js +166 -0
- package/dist/schema.js.map +1 -0
- package/dist/test-dashboard.d.ts +5 -0
- package/dist/test-dashboard.d.ts.map +1 -0
- package/dist/test-dashboard.js +202 -0
- package/dist/test-dashboard.js.map +1 -0
- package/dist/tools.d.ts +27 -0
- package/dist/tools.d.ts.map +1 -0
- package/dist/tools.js +1212 -0
- package/dist/tools.js.map +1 -0
- package/dist/types.d.ts +180 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +14 -0
- package/dist/types.js.map +1 -0
- package/dist/worktree.d.ts +50 -0
- package/dist/worktree.d.ts.map +1 -0
- package/dist/worktree.js +186 -0
- package/dist/worktree.js.map +1 -0
- package/package.json +67 -0
package/.env.example
ADDED
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
# ╔══════════════════════════════════════════════════════════╗
|
|
2
|
+
# ║ NotSleep Configuration ║
|
|
3
|
+
# ╚══════════════════════════════════════════════════════════╝
|
|
4
|
+
#
|
|
5
|
+
# Copy file ini jadi .env lalu isi sesuai kebutuhan:
|
|
6
|
+
# copy .env.example .env
|
|
7
|
+
#
|
|
8
|
+
|
|
9
|
+
# ─── Provider ────────────────────────────────────────────
|
|
10
|
+
# Pilih: "openai" atau "anthropic"
|
|
11
|
+
NOTSLEEP_PROVIDER=openai
|
|
12
|
+
|
|
13
|
+
# ─── OpenAI ──────────────────────────────────────────────
|
|
14
|
+
OPENAI_API_KEY=sk-...
|
|
15
|
+
OPENAI_MODEL=gpt-4o
|
|
16
|
+
# Custom base URL (untuk Azure, local proxy, LM Studio, Ollama, dll)
|
|
17
|
+
# OPENAI_BASE_URL=https://api.openai.com/v1
|
|
18
|
+
|
|
19
|
+
# ─── Anthropic ───────────────────────────────────────────
|
|
20
|
+
ANTHROPIC_API_KEY=sk-ant-...
|
|
21
|
+
ANTHROPIC_MODEL=claude-sonnet-4-20250514
|
|
22
|
+
# ANTHROPIC_BASE_URL=https://api.anthropic.com
|
|
23
|
+
|
|
24
|
+
# ─── Registry model (gaya OpenCode / models.dev) ─────────
|
|
25
|
+
# Alih-alih pilih provider + model terpisah, cukup satu string "provider/model".
|
|
26
|
+
# NotSleep sudah punya baseURL bawaan untuk provider populer di bawah — kamu
|
|
27
|
+
# tinggal isi API key-nya. Aktifkan dengan NOTSLEEP_MODEL atau field "model"
|
|
28
|
+
# di notsleep.json, atau flag --model provider/model.
|
|
29
|
+
# NOTSLEEP_MODEL=groq/llama-3.3-70b-versatile
|
|
30
|
+
#
|
|
31
|
+
# Model murah untuk kerja internal agent (summarize context, generate task).
|
|
32
|
+
# Bisa "provider/model" atau id polos (pakai kredensial provider utama).
|
|
33
|
+
# NOTSLEEP_SMALL_MODEL=groq/llama-3.1-8b-instant
|
|
34
|
+
#
|
|
35
|
+
# Provider bawaan (isi key yang relevan saja):
|
|
36
|
+
# openai/... OPENAI_API_KEY
|
|
37
|
+
# anthropic/... ANTHROPIC_API_KEY (SDK native)
|
|
38
|
+
# openrouter/... OPENROUTER_API_KEY (mis. openrouter/anthropic/claude-3.5-sonnet)
|
|
39
|
+
# groq/... GROQ_API_KEY
|
|
40
|
+
# deepseek/... DEEPSEEK_API_KEY
|
|
41
|
+
# together/... TOGETHER_API_KEY
|
|
42
|
+
# xai/... XAI_API_KEY
|
|
43
|
+
# fireworks/... FIREWORKS_API_KEY
|
|
44
|
+
# mistral/... MISTRAL_API_KEY
|
|
45
|
+
# perplexity/... PERPLEXITY_API_KEY
|
|
46
|
+
# gemini/... GEMINI_API_KEY
|
|
47
|
+
# ollama/... (lokal, tanpa key)
|
|
48
|
+
# limitrouter/... OPENAI_API_KEY
|
|
49
|
+
# GROQ_API_KEY=gsk-...
|
|
50
|
+
# OPENROUTER_API_KEY=sk-or-...
|
|
51
|
+
|
|
52
|
+
# ─── Agent Behavior ─────────────────────────────────────
|
|
53
|
+
# Max loop iterations sebelum agent berhenti paksa
|
|
54
|
+
NOTSLEEP_MAX_ITERATIONS=1000
|
|
55
|
+
|
|
56
|
+
# Continuous mode: setelah 1 task selesai, otomatis lanjut task berikutnya
|
|
57
|
+
# true = agent tidak berhenti sampai queue kosong / kamu stop manual
|
|
58
|
+
# false = agent berhenti setelah 1 task selesai
|
|
59
|
+
NOTSLEEP_CONTINUOUS=false
|
|
60
|
+
|
|
61
|
+
# ─── Context Window Management ──────────────────────────
|
|
62
|
+
# Batas token context window. KOSONGKAN / 0 = auto-detect dari model.
|
|
63
|
+
# Auto-detect sync live dari models.dev (di-cache 24 jam), fallback ke
|
|
64
|
+
# endpoint /models provider, lalu ke tabel statis. Isi manual hanya kalau
|
|
65
|
+
# mau override.
|
|
66
|
+
# NOTSLEEP_CONTEXT_WINDOW_LIMIT=120000
|
|
67
|
+
#
|
|
68
|
+
# Matikan sync jaringan model metadata (offline / air-gapped): pakai cache
|
|
69
|
+
# atau tabel statis saja.
|
|
70
|
+
# NOTSLEEP_NO_MODEL_SYNC=1
|
|
71
|
+
|
|
72
|
+
# Kapan mulai summarize (0.75 = kalau context sudah 75% penuh)
|
|
73
|
+
NOTSLEEP_SUMMARIZE_THRESHOLD=0.75
|
|
74
|
+
|
|
75
|
+
# ─── Error Handling ─────────────────────────────────────
|
|
76
|
+
# Max retry kalau API error (rate limit, server error, network)
|
|
77
|
+
NOTSLEEP_MAX_RETRIES=10
|
|
78
|
+
|
|
79
|
+
# Base delay untuk exponential backoff (ms)
|
|
80
|
+
NOTSLEEP_RETRY_BASE_DELAY_MS=1000
|
|
81
|
+
|
|
82
|
+
# Timeout untuk tool execution (ms) - default 2 menit
|
|
83
|
+
NOTSLEEP_TOOL_TIMEOUT_MS=120000
|
|
84
|
+
|
|
85
|
+
# ─── Web Dashboard ──────────────────────────────────────
|
|
86
|
+
# Aktifkan dashboard otomatis tanpa flag --ui
|
|
87
|
+
# NOTSLEEP_DASHBOARD=true
|
|
88
|
+
# Port untuk web dashboard (aktifkan dengan --ui)
|
|
89
|
+
NOTSLEEP_DASHBOARD_PORT=3120
|
|
90
|
+
|
|
91
|
+
# ─── Storage ────────────────────────────────────────────
|
|
92
|
+
# Folder untuk simpan checkpoint (crash recovery)
|
|
93
|
+
NOTSLEEP_CHECKPOINT_DIR=.notsleep/checkpoints
|
|
94
|
+
|
|
95
|
+
# Folder untuk simpan log files
|
|
96
|
+
NOTSLEEP_LOG_DIR=.notsleep/logs
|
|
97
|
+
|
|
98
|
+
# File yang kalau dibuat, agent akan berhenti
|
|
99
|
+
# Cara stop: echo. > .notsleep/STOP
|
|
100
|
+
NOTSLEEP_STOP_FILE=.notsleep/STOP
|
|
101
|
+
|
|
102
|
+
# ─── Config File (alternatif .env) ──────────────────────
|
|
103
|
+
# Selain .env, kamu bisa pakai file JSON: notsleep.json (project)
|
|
104
|
+
# atau ~/.notsleep/config.json (global). Bikin dengan wizard:
|
|
105
|
+
# notsleep init # bikin notsleep.json di project ini
|
|
106
|
+
# notsleep init --global # bikin config global
|
|
107
|
+
# notsleep config # lihat config final + sumbernya
|
|
108
|
+
#
|
|
109
|
+
# Prioritas (yang atas menang):
|
|
110
|
+
# 1. CLI flags (--model, --provider, dst)
|
|
111
|
+
# 2. notsleep.json (project)
|
|
112
|
+
# 3. ~/.notsleep/config.json (global)
|
|
113
|
+
# 4. .env / environment
|
|
114
|
+
# 5. default bawaan
|
|
115
|
+
#
|
|
116
|
+
# Di notsleep.json, API key bisa pakai referensi env biar aman:
|
|
117
|
+
# "apiKey": "{env:OPENAI_API_KEY}"
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 yudarmd
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,341 @@
|
|
|
1
|
+
# NotSleep
|
|
2
|
+
|
|
3
|
+
[](https://github.com/yudarmd/notsleep-agent/actions/workflows/ci.yml)
|
|
4
|
+
[](LICENSE)
|
|
5
|
+
[](package.json)
|
|
6
|
+
|
|
7
|
+
**Long-horizon autonomous AI agent - "Do not stop until I woke up"**
|
|
8
|
+
|
|
9
|
+
An AI agent that runs autonomously for hours or days, managing its own context window, checkpointing progress, retrying on failures, and never stopping until the task is fully complete. Compatible with both OpenAI and Anthropic APIs.
|
|
10
|
+
|
|
11
|
+
> ### ⚠️ Safety first — read before running
|
|
12
|
+
>
|
|
13
|
+
> NotSleep is **autonomous**: it runs shell commands, reads/writes files, and
|
|
14
|
+
> fetches URLs on its own, in a loop, without asking for approval. In-code
|
|
15
|
+
> guards ([`src/safety.ts`](src/safety.ts)) confine file writes to the workspace
|
|
16
|
+
> and block destructive commands, but they reduce risk rather than eliminate it.
|
|
17
|
+
>
|
|
18
|
+
> - Run untrusted or open-ended tasks in a **sandbox / container / VM**.
|
|
19
|
+
> - Use a **dedicated API key** and a budget (`--max-cost`) — autonomous runs
|
|
20
|
+
> can be expensive.
|
|
21
|
+
> - Keep the **dashboard local** (it has no auth; binds to `127.0.0.1`).
|
|
22
|
+
>
|
|
23
|
+
> See [SECURITY.md](SECURITY.md) for the full security model and how to report
|
|
24
|
+
> vulnerabilities.
|
|
25
|
+
|
|
26
|
+
## Features
|
|
27
|
+
|
|
28
|
+
- **Dual Provider Support** - OpenAI (GPT-4o, o1, etc.) and Anthropic (Claude) with a unified interface
|
|
29
|
+
- **Long-Horizon Execution** - Automatic context window management with summarization when context gets full
|
|
30
|
+
- **Crash Recovery** - Periodic checkpoints to disk; resume from where you left off after a crash
|
|
31
|
+
- **Resilient Retries** - Exponential backoff with jitter, rate-limit awareness, Retry-After header support
|
|
32
|
+
- **Built-in Tools** - Shell execution, file read/write/edit, directory listing, file search, web fetch
|
|
33
|
+
- **Extensible** - Add custom tools via the programmatic API
|
|
34
|
+
- **Progress Tracking** - Real-time progress bar, elapsed time, token usage, iteration count
|
|
35
|
+
- **Full Logging** - Every action logged to disk with timestamps
|
|
36
|
+
|
|
37
|
+
## Quick Start
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
# Install dependencies
|
|
41
|
+
npm install
|
|
42
|
+
|
|
43
|
+
# Build
|
|
44
|
+
npm run build
|
|
45
|
+
|
|
46
|
+
# Configure (copy and edit)
|
|
47
|
+
cp .env.example .env
|
|
48
|
+
# Edit .env with your API keys
|
|
49
|
+
|
|
50
|
+
# Run with a task
|
|
51
|
+
npm start -- "Build a REST API with Express, add user auth, and write tests"
|
|
52
|
+
|
|
53
|
+
# Or use dev mode (no build needed)
|
|
54
|
+
npm run dev -- "Refactor all callbacks to async/await in the src directory"
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## CLI Usage
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
# Basic usage
|
|
61
|
+
notsleep "Your task description here"
|
|
62
|
+
|
|
63
|
+
# Use Anthropic instead of OpenAI
|
|
64
|
+
notsleep --provider anthropic "Your task"
|
|
65
|
+
|
|
66
|
+
# Specify model
|
|
67
|
+
notsleep --model gpt-4o "Your task"
|
|
68
|
+
|
|
69
|
+
# Resume from last checkpoint
|
|
70
|
+
notsleep --resume
|
|
71
|
+
|
|
72
|
+
# Read task from a file
|
|
73
|
+
notsleep --task-file task.md
|
|
74
|
+
|
|
75
|
+
# Custom system prompt
|
|
76
|
+
notsleep --system-prompt-file system.md "Your task"
|
|
77
|
+
|
|
78
|
+
# Pass API key directly
|
|
79
|
+
notsleep --openai-key sk-... "Your task"
|
|
80
|
+
|
|
81
|
+
# Custom base URL (Azure, local proxy, etc.)
|
|
82
|
+
notsleep --base-url http://localhost:8080/v1 "Your task"
|
|
83
|
+
|
|
84
|
+
# Verbose mode
|
|
85
|
+
notsleep --verbose "Your task"
|
|
86
|
+
|
|
87
|
+
# Set max iterations
|
|
88
|
+
notsleep --max-iterations 500 "Your task"
|
|
89
|
+
|
|
90
|
+
# ─── Config management ───
|
|
91
|
+
# Create a project config file (interactive wizard)
|
|
92
|
+
notsleep init
|
|
93
|
+
|
|
94
|
+
# Create a global config (~/.notsleep/config.json)
|
|
95
|
+
notsleep init --global
|
|
96
|
+
|
|
97
|
+
# Non-interactive: write sensible defaults
|
|
98
|
+
notsleep init --yes
|
|
99
|
+
|
|
100
|
+
# Show the resolved config and where each value came from
|
|
101
|
+
notsleep config
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
## Configuration
|
|
105
|
+
|
|
106
|
+
You can configure NotSleep three ways: a **config file** (`notsleep.json`),
|
|
107
|
+
a **`.env` file**, or **CLI flags**. They merge together, highest priority wins:
|
|
108
|
+
|
|
109
|
+
```
|
|
110
|
+
1. CLI flags (--model, --provider, ...) ← highest
|
|
111
|
+
2. notsleep.json (project, searched upward)
|
|
112
|
+
3. ~/.notsleep/config.json (global user defaults)
|
|
113
|
+
4. .env / environment
|
|
114
|
+
5. built-in defaults ← lowest
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
### Config file (`notsleep.json`)
|
|
118
|
+
|
|
119
|
+
Run `notsleep init` to generate one. Example:
|
|
120
|
+
|
|
121
|
+
```json
|
|
122
|
+
{
|
|
123
|
+
"$schema": "https://notsleep.dev/config-schema.json",
|
|
124
|
+
"provider": "openai",
|
|
125
|
+
"openai": {
|
|
126
|
+
"apiKey": "{env:OPENAI_API_KEY}",
|
|
127
|
+
"model": "gpt-4o"
|
|
128
|
+
},
|
|
129
|
+
"anthropic": {
|
|
130
|
+
"apiKey": "{env:ANTHROPIC_API_KEY}",
|
|
131
|
+
"model": "claude-sonnet-4-20250514"
|
|
132
|
+
},
|
|
133
|
+
"maxIterations": 1000,
|
|
134
|
+
"contextWindowLimit": 120000,
|
|
135
|
+
"continuous": false,
|
|
136
|
+
"dashboard": { "enabled": false, "port": 3120 }
|
|
137
|
+
}
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
### Registry models — `provider/model` (OpenCode / models.dev style)
|
|
141
|
+
|
|
142
|
+
Instead of the separate `provider` + `openai`/`anthropic` blocks, you can pick a
|
|
143
|
+
model with a single unified string. NotSleep ships baseURLs for popular
|
|
144
|
+
providers, so you only supply an API key:
|
|
145
|
+
|
|
146
|
+
```json
|
|
147
|
+
{
|
|
148
|
+
"model": "groq/llama-3.3-70b-versatile",
|
|
149
|
+
"providers": {
|
|
150
|
+
"groq": { "apiKey": "{env:GROQ_API_KEY}" },
|
|
151
|
+
"myproxy": {
|
|
152
|
+
"baseURL": "https://limitrouter.com/v1",
|
|
153
|
+
"apiKey": "{env:OPENAI_API_KEY}"
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
- `model` is `"<provider>/<modelId>"`. The model id may itself contain slashes
|
|
160
|
+
(e.g. `"openrouter/anthropic/claude-3.5-sonnet"`).
|
|
161
|
+
- Built-in providers: `openai, anthropic, openrouter, groq, deepseek, together,
|
|
162
|
+
xai, fireworks, mistral, perplexity, gemini, ollama, limitrouter`. For known
|
|
163
|
+
ones you only need the key; the key is read from that provider's env var
|
|
164
|
+
automatically (`GROQ_API_KEY`, `OPENROUTER_API_KEY`, …) unless you set one in
|
|
165
|
+
`providers`.
|
|
166
|
+
- Define any **new** provider under `providers` with its `baseURL` + `apiKey`
|
|
167
|
+
(and optional `type`, default `openai`). Almost every provider is
|
|
168
|
+
OpenAI-compatible; only `anthropic`-type uses the native SDK.
|
|
169
|
+
- Works on the CLI too: `notsleep --model openrouter/anthropic/claude-3.5-sonnet "..."`.
|
|
170
|
+
|
|
171
|
+
The legacy `provider` + blocks still work; `model` simply takes precedence when
|
|
172
|
+
present.
|
|
173
|
+
|
|
174
|
+
### A cheaper model for internal work — `small_model`
|
|
175
|
+
|
|
176
|
+
The agent makes internal calls of its own — summarizing context when it fills
|
|
177
|
+
up, and generating follow-up tasks in continuous mode. Point those at a cheaper
|
|
178
|
+
model so they don't burn your primary one (OpenCode-style):
|
|
179
|
+
|
|
180
|
+
```json
|
|
181
|
+
{
|
|
182
|
+
"model": "anthropic/claude-sonnet-4-20250514",
|
|
183
|
+
"small_model": "anthropic/claude-3-5-haiku"
|
|
184
|
+
}
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
`small_model` accepts a `provider/model` ref (its own provider/creds) **or** a
|
|
188
|
+
bare model id, which reuses the primary provider's key + base URL (e.g. primary
|
|
189
|
+
`gpt-4o`, `small_model: "gpt-4o-mini"`). CLI: `--small-model`. Unset → internal
|
|
190
|
+
calls use the primary model.
|
|
191
|
+
|
|
192
|
+
### Config ergonomics — JSONC, file refs, instructions, schema
|
|
193
|
+
|
|
194
|
+
- **Comments + trailing commas (JSONC):** `notsleep.json` may contain `//` and
|
|
195
|
+
`/* */` comments and trailing commas.
|
|
196
|
+
- **`{file:./path}` references:** any string value can inline a file's contents,
|
|
197
|
+
resolved relative to the config, e.g. `"systemPrompt": "{file:./prompt.md}"`.
|
|
198
|
+
- **`instructions` + auto-loaded `AGENTS.md`:** list instruction files whose
|
|
199
|
+
contents are appended to the system prompt; `AGENTS.md` / `NOTSLEEP.md` in the
|
|
200
|
+
project root are picked up automatically (the emerging cross-agent standard).
|
|
201
|
+
|
|
202
|
+
```json
|
|
203
|
+
{ "instructions": ["./docs/style.md"] }
|
|
204
|
+
```
|
|
205
|
+
- **IDE autocomplete, fully offline:** `notsleep init` writes a local
|
|
206
|
+
`notsleep.schema.json` beside the config and points `$schema` at it (no hosted
|
|
207
|
+
URL). Regenerate anytime with `notsleep schema`.
|
|
208
|
+
|
|
209
|
+
### Context window — live-synced with the API
|
|
210
|
+
|
|
211
|
+
The agent decides when to summarize from a ratio: **current tokens ÷ window
|
|
212
|
+
limit**. The numerator is already the *real* `prompt_tokens` the API reports on
|
|
213
|
+
every call. The denominator (the model's max window) is resolved live, in three
|
|
214
|
+
layers, so it stays right even for brand-new models:
|
|
215
|
+
|
|
216
|
+
1. **models.dev** — the `models.dev/api.json` catalog (the same source OpenCode
|
|
217
|
+
uses) is fetched once, cached to `~/.notsleep/models.dev.json` (24h TTL), and
|
|
218
|
+
gives the exact context window + pricing for ~all providers/models.
|
|
219
|
+
2. **`/models` endpoint** — for a custom proxy or a model the catalog doesn't
|
|
220
|
+
list, the provider's own OpenAI-style `GET /models` is queried for
|
|
221
|
+
`context_length`.
|
|
222
|
+
3. **static table** — a built-in offline fallback (in `cost.ts`) when both are
|
|
223
|
+
unavailable.
|
|
224
|
+
|
|
225
|
+
On top of that, if a request is ever rejected for exceeding the window, the
|
|
226
|
+
agent reads the true maximum out of the provider's error, shrinks its limit, and
|
|
227
|
+
summarizes — self-correcting even if every source above was wrong.
|
|
228
|
+
|
|
229
|
+
`notsleep config` shows the resolved limit and where it came from
|
|
230
|
+
(`models.dev` / `/models endpoint` / `static table` / `set`). Set
|
|
231
|
+
`contextWindowLimit` in config to pin it manually, or `NOTSLEEP_NO_MODEL_SYNC=1`
|
|
232
|
+
to disable the network sync entirely (offline / air-gapped use).
|
|
233
|
+
|
|
234
|
+
The config file is searched from the current directory **upward**, so it works
|
|
235
|
+
from any subfolder of your project (like `.git` or `package.json`).
|
|
236
|
+
|
|
237
|
+
**Keep secrets out of the file** with `{env:VAR}` references. `"{env:OPENAI_API_KEY}"`
|
|
238
|
+
reads from your environment / `.env` at runtime, so the config is safe to commit.
|
|
239
|
+
You can also reference a system prompt from disk with `"systemPromptFile": "prompt.md"`.
|
|
240
|
+
|
|
241
|
+
### `.env` variables
|
|
242
|
+
|
|
243
|
+
All settings can also be configured via `.env` file or CLI flags:
|
|
244
|
+
|
|
245
|
+
| Variable | Default | Description |
|
|
246
|
+
|---|---|---|
|
|
247
|
+
| `NOTSLEEP_PROVIDER` | `openai` | LLM provider (`openai` or `anthropic`) |
|
|
248
|
+
| `OPENAI_API_KEY` | - | Your OpenAI API key |
|
|
249
|
+
| `OPENAI_MODEL` | `gpt-4o` | OpenAI model to use |
|
|
250
|
+
| `OPENAI_BASE_URL` | - | Custom base URL for OpenAI-compatible APIs |
|
|
251
|
+
| `ANTHROPIC_API_KEY` | - | Your Anthropic API key |
|
|
252
|
+
| `ANTHROPIC_MODEL` | `claude-sonnet-4-20250514` | Anthropic model to use |
|
|
253
|
+
| `NOTSLEEP_MAX_ITERATIONS` | `1000` | Maximum agent loop iterations |
|
|
254
|
+
| `NOTSLEEP_CONTEXT_WINDOW_LIMIT` | `120000` | Context window size in tokens |
|
|
255
|
+
| `NOTSLEEP_SUMMARIZE_THRESHOLD` | `0.75` | Summarize when context reaches this % |
|
|
256
|
+
| `NOTSLEEP_MAX_RETRIES` | `10` | Max retries on transient errors |
|
|
257
|
+
| `NOTSLEEP_RETRY_BASE_DELAY_MS` | `1000` | Base delay for exponential backoff |
|
|
258
|
+
| `NOTSLEEP_TOOL_TIMEOUT_MS` | `120000` | Timeout for tool execution |
|
|
259
|
+
|
|
260
|
+
## Programmatic API
|
|
261
|
+
|
|
262
|
+
```typescript
|
|
263
|
+
import { Agent, loadConfig, Logger, LogLevel } from 'notsleep/api';
|
|
264
|
+
|
|
265
|
+
const config = loadConfig({
|
|
266
|
+
provider: 'openai',
|
|
267
|
+
openai: { apiKey: 'sk-...', model: 'gpt-4o' },
|
|
268
|
+
maxIterations: 100,
|
|
269
|
+
});
|
|
270
|
+
|
|
271
|
+
const logger = new Logger('.notsleep/logs', LogLevel.INFO);
|
|
272
|
+
const agent = new Agent(config, logger);
|
|
273
|
+
|
|
274
|
+
// Add custom tools
|
|
275
|
+
agent.addTool({
|
|
276
|
+
name: 'my_tool',
|
|
277
|
+
description: 'Does something custom',
|
|
278
|
+
parameters: {
|
|
279
|
+
type: 'object',
|
|
280
|
+
properties: { input: { type: 'string' } },
|
|
281
|
+
required: ['input'],
|
|
282
|
+
},
|
|
283
|
+
execute: async (args) => {
|
|
284
|
+
return `Result for ${args.input}`;
|
|
285
|
+
},
|
|
286
|
+
});
|
|
287
|
+
|
|
288
|
+
// Run the agent
|
|
289
|
+
const result = await agent.run('Build and deploy the application');
|
|
290
|
+
console.log(result.success, result.summary, result.stats);
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
## Built-in Tools
|
|
294
|
+
|
|
295
|
+
| Tool | Description |
|
|
296
|
+
|---|---|
|
|
297
|
+
| `shell` | Execute shell commands (bash/powershell) |
|
|
298
|
+
| `read_file` | Read file contents with line numbers |
|
|
299
|
+
| `write_file` | Create or overwrite files |
|
|
300
|
+
| `edit_file` | Search-and-replace edits in files |
|
|
301
|
+
| `list_dir` | List directory contents |
|
|
302
|
+
| `search_files` | Grep/regex search across files |
|
|
303
|
+
| `web_fetch` | Fetch content from URLs |
|
|
304
|
+
| `think` | Scratchpad for reasoning and planning |
|
|
305
|
+
| `task_complete` | Signal that the task is done |
|
|
306
|
+
|
|
307
|
+
## How Long-Horizon Works
|
|
308
|
+
|
|
309
|
+
1. **Iterative Loop**: The agent calls the LLM, processes tool calls, and repeats
|
|
310
|
+
2. **Context Management**: When the conversation approaches the context limit (~75%), the agent summarizes all progress into a compressed report and starts fresh with that summary
|
|
311
|
+
3. **Checkpointing**: Every 5 iterations, the full state is saved to disk. If the process crashes, use `--resume` to continue
|
|
312
|
+
4. **Error Recovery**: Transient API errors (429, 500, network) are retried with exponential backoff. Tool errors are fed back to the agent so it can self-correct
|
|
313
|
+
5. **Completion**: The agent runs until it calls `task_complete` or hits the iteration limit
|
|
314
|
+
|
|
315
|
+
## Architecture
|
|
316
|
+
|
|
317
|
+
```
|
|
318
|
+
src/
|
|
319
|
+
index.ts - CLI entry point
|
|
320
|
+
api.ts - Public programmatic API exports
|
|
321
|
+
types.ts - TypeScript type definitions
|
|
322
|
+
config.ts - Configuration loader (merges file + .env + CLI args)
|
|
323
|
+
fileconfig.ts - notsleep.json loader, env-ref resolver, merge logic
|
|
324
|
+
init.ts - `notsleep init` interactive setup wizard
|
|
325
|
+
provider.ts - Unified LLM provider (OpenAI + Anthropic)
|
|
326
|
+
agent.ts - Core agent loop (the brain)
|
|
327
|
+
tools.ts - Built-in tool definitions
|
|
328
|
+
checkpoint.ts - Checkpoint save/load for crash recovery
|
|
329
|
+
logger.ts - Structured logging with colors
|
|
330
|
+
```
|
|
331
|
+
|
|
332
|
+
## Contributing
|
|
333
|
+
|
|
334
|
+
Contributions are welcome! See [CONTRIBUTING.md](CONTRIBUTING.md) for setup,
|
|
335
|
+
build/test commands, and the PR process, and please follow our
|
|
336
|
+
[Code of Conduct](CODE_OF_CONDUCT.md). Changes are tracked in
|
|
337
|
+
[CHANGELOG.md](CHANGELOG.md).
|
|
338
|
+
|
|
339
|
+
## License
|
|
340
|
+
|
|
341
|
+
[MIT](LICENSE) © yudarmd
|