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.
Files changed (93) hide show
  1. package/.env.example +117 -0
  2. package/LICENSE +21 -0
  3. package/README.md +341 -0
  4. package/dashboard/index.html +893 -0
  5. package/dist/agent.d.ts +162 -0
  6. package/dist/agent.d.ts.map +1 -0
  7. package/dist/agent.js +1064 -0
  8. package/dist/agent.js.map +1 -0
  9. package/dist/api.d.ts +10 -0
  10. package/dist/api.d.ts.map +1 -0
  11. package/dist/api.js +39 -0
  12. package/dist/api.js.map +1 -0
  13. package/dist/checkpoint.d.ts +52 -0
  14. package/dist/checkpoint.d.ts.map +1 -0
  15. package/dist/checkpoint.js +234 -0
  16. package/dist/checkpoint.js.map +1 -0
  17. package/dist/config.d.ts +24 -0
  18. package/dist/config.d.ts.map +1 -0
  19. package/dist/config.js +265 -0
  20. package/dist/config.js.map +1 -0
  21. package/dist/context.d.ts +15 -0
  22. package/dist/context.d.ts.map +1 -0
  23. package/dist/context.js +237 -0
  24. package/dist/context.js.map +1 -0
  25. package/dist/cost.d.ts +26 -0
  26. package/dist/cost.d.ts.map +1 -0
  27. package/dist/cost.js +161 -0
  28. package/dist/cost.js.map +1 -0
  29. package/dist/dashboard.d.ts +96 -0
  30. package/dist/dashboard.d.ts.map +1 -0
  31. package/dist/dashboard.js +292 -0
  32. package/dist/dashboard.js.map +1 -0
  33. package/dist/fileconfig.d.ts +129 -0
  34. package/dist/fileconfig.d.ts.map +1 -0
  35. package/dist/fileconfig.js +391 -0
  36. package/dist/fileconfig.js.map +1 -0
  37. package/dist/index.d.ts +3 -0
  38. package/dist/index.d.ts.map +1 -0
  39. package/dist/index.js +882 -0
  40. package/dist/index.js.map +1 -0
  41. package/dist/init.d.ts +9 -0
  42. package/dist/init.d.ts.map +1 -0
  43. package/dist/init.js +221 -0
  44. package/dist/init.js.map +1 -0
  45. package/dist/logger.d.ts +33 -0
  46. package/dist/logger.d.ts.map +1 -0
  47. package/dist/logger.js +150 -0
  48. package/dist/logger.js.map +1 -0
  49. package/dist/modelsdev.d.ts +63 -0
  50. package/dist/modelsdev.d.ts.map +1 -0
  51. package/dist/modelsdev.js +265 -0
  52. package/dist/modelsdev.js.map +1 -0
  53. package/dist/parallel.d.ts +54 -0
  54. package/dist/parallel.d.ts.map +1 -0
  55. package/dist/parallel.js +139 -0
  56. package/dist/parallel.js.map +1 -0
  57. package/dist/pool.d.ts +17 -0
  58. package/dist/pool.d.ts.map +1 -0
  59. package/dist/pool.js +53 -0
  60. package/dist/pool.js.map +1 -0
  61. package/dist/provider.d.ts +60 -0
  62. package/dist/provider.d.ts.map +1 -0
  63. package/dist/provider.js +396 -0
  64. package/dist/provider.js.map +1 -0
  65. package/dist/registry.d.ts +60 -0
  66. package/dist/registry.d.ts.map +1 -0
  67. package/dist/registry.js +153 -0
  68. package/dist/registry.js.map +1 -0
  69. package/dist/safety.d.ts +21 -0
  70. package/dist/safety.d.ts.map +1 -0
  71. package/dist/safety.js +118 -0
  72. package/dist/safety.js.map +1 -0
  73. package/dist/schema.d.ts +9 -0
  74. package/dist/schema.d.ts.map +1 -0
  75. package/dist/schema.js +166 -0
  76. package/dist/schema.js.map +1 -0
  77. package/dist/test-dashboard.d.ts +5 -0
  78. package/dist/test-dashboard.d.ts.map +1 -0
  79. package/dist/test-dashboard.js +202 -0
  80. package/dist/test-dashboard.js.map +1 -0
  81. package/dist/tools.d.ts +27 -0
  82. package/dist/tools.d.ts.map +1 -0
  83. package/dist/tools.js +1212 -0
  84. package/dist/tools.js.map +1 -0
  85. package/dist/types.d.ts +180 -0
  86. package/dist/types.d.ts.map +1 -0
  87. package/dist/types.js +14 -0
  88. package/dist/types.js.map +1 -0
  89. package/dist/worktree.d.ts +50 -0
  90. package/dist/worktree.d.ts.map +1 -0
  91. package/dist/worktree.js +186 -0
  92. package/dist/worktree.js.map +1 -0
  93. 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
+ [![CI](https://github.com/yudarmd/notsleep-agent/actions/workflows/ci.yml/badge.svg)](https://github.com/yudarmd/notsleep-agent/actions/workflows/ci.yml)
4
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
5
+ [![Node](https://img.shields.io/badge/node-%3E%3D18-brightgreen)](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