limbo-ai 1.24.7 → 1.24.9
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/README.md +116 -150
- package/package.json +1 -1
- package/setup-server/server.js +11 -26
- package/test/setup-server.test.js +0 -19
package/README.md
CHANGED
|
@@ -1,143 +1,104 @@
|
|
|
1
1
|
# Limbo
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
[](https://www.npmjs.com/package/limbo-ai)
|
|
4
|
+
[](https://github.com/TomasWard1/limbo/actions)
|
|
5
|
+
[](./LICENSE)
|
|
6
|
+
[](.)
|
|
7
|
+
[](https://github.com/TomasWard1/limbo/pkgs/container/limbo)
|
|
4
8
|
|
|
5
|
-
|
|
9
|
+
A personal memory agent. Captures ideas, remembers things, and connects knowledge across time — running in a Docker container, accessible via Telegram or the ZeroClaw gateway.
|
|
6
10
|
|
|
7
|
-
Limbo is a second brain with a conversational interface. It stores atomic notes in a local vault, searches them semantically, and maintains Maps of Content (MOCs) to keep knowledge navigable.
|
|
8
|
-
|
|
9
|
-
**Agent personality:** defined in `workspace/IDENTITY.md` and `workspace/SOUL.md`, baked into the image at build time.
|
|
11
|
+
Limbo is a second brain with a conversational interface. It stores atomic notes in a local vault, searches them semantically, and maintains Maps of Content (MOCs) to keep knowledge navigable.
|
|
10
12
|
|
|
11
13
|
---
|
|
12
14
|
|
|
13
|
-
##
|
|
14
|
-
|
|
15
|
-
Limbo runs as a single Docker container (~35 MB RAM at idle). The main resource cost is Docker and the host OS, not Limbo itself.
|
|
16
|
-
|
|
17
|
-
| Tier | RAM | vCPU | Disk | Notes |
|
|
18
|
-
|------|-----|------|------|-------|
|
|
19
|
-
| Minimum | 512 MB | 1 | 1 GB | Needs swap configured |
|
|
20
|
-
| Recommended | 1 GB | 1 | 5 GB | Comfortable for Limbo alone |
|
|
21
|
-
| With other services | 2 GB | 1 | 10 GB | Room for reverse proxy, monitoring, etc. |
|
|
15
|
+
## Install
|
|
22
16
|
|
|
23
|
-
> Limbo
|
|
17
|
+
> Limbo is designed to run on a VPS (always-on, accessible from anywhere). A $5/month Ubuntu server is all you need.
|
|
24
18
|
|
|
25
|
-
|
|
19
|
+
### 1. Provision a server
|
|
26
20
|
|
|
27
|
-
|
|
21
|
+
Any Ubuntu/Debian VPS with 1 GB+ RAM. Recommended providers: Hetzner, DigitalOcean, Vultr, ReliedCloud.
|
|
28
22
|
|
|
29
|
-
|
|
23
|
+
### 2. Run the installer
|
|
30
24
|
|
|
31
|
-
```
|
|
32
|
-
|
|
25
|
+
```bash
|
|
26
|
+
curl -fsSL https://raw.githubusercontent.com/TomasWard1/limbo/main/scripts/install.sh | bash
|
|
33
27
|
```
|
|
34
28
|
|
|
35
|
-
This
|
|
36
|
-
1. Prompt for your API key (Anthropic or OpenAI)
|
|
37
|
-
2. Write `~/.limbo/.env` and `~/.limbo/docker-compose.yml`
|
|
38
|
-
3. Pull the latest Limbo image and start the container
|
|
29
|
+
This installs Docker, Node.js, and the Limbo CLI.
|
|
39
30
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
### Agent Installation
|
|
43
|
-
|
|
44
|
-
AI agents can install Limbo non-interactively using CLI flags:
|
|
31
|
+
### 3. Start Limbo
|
|
45
32
|
|
|
46
33
|
```bash
|
|
47
|
-
|
|
34
|
+
limbo start
|
|
48
35
|
```
|
|
49
36
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|------|---------|-------------|
|
|
59
|
-
| `--model` | Provider default | Model name (e.g. `anthropic/claude-sonnet-4-6`) |
|
|
60
|
-
| `--language` | `en` | CLI language (`en` or `es`) |
|
|
61
|
-
|
|
62
|
-
Headless mode skips Telegram setup. To add Telegram later, run `npx limbo-ai start --reconfigure`.
|
|
37
|
+
The setup wizard walks you through:
|
|
38
|
+
- [ ] Choose a language (English / Español)
|
|
39
|
+
- [ ] Select a provider (Anthropic, OpenAI, OpenRouter)
|
|
40
|
+
- [ ] Authenticate (API key or Claude/ChatGPT subscription)
|
|
41
|
+
- [ ] Pick a model
|
|
42
|
+
- [ ] Connect Telegram (optional but recommended)
|
|
43
|
+
- [ ] Enable voice messages and web search (optional)
|
|
44
|
+
- [ ] Review and confirm
|
|
63
45
|
|
|
64
|
-
|
|
46
|
+
Once complete, Limbo restarts and is ready to use.
|
|
65
47
|
|
|
66
|
-
###
|
|
48
|
+
### 4. Update
|
|
67
49
|
|
|
68
|
-
```
|
|
69
|
-
|
|
70
|
-
npx limbo-ai@latest stop # Stop the container
|
|
71
|
-
npx limbo-ai@latest update # Pull latest image and restart
|
|
72
|
-
npx limbo-ai@latest status # Show container status
|
|
73
|
-
npx limbo-ai@latest logs # Tail container logs
|
|
74
|
-
npx limbo-ai@latest start --reconfigure # Change API keys or settings
|
|
75
|
-
npx limbo-ai@latest config # Configure optional features (voice, web-search)
|
|
50
|
+
```bash
|
|
51
|
+
limbo update
|
|
76
52
|
```
|
|
77
53
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
## Optional Features
|
|
81
|
-
|
|
82
|
-
Limbo supports optional features that can be enabled during the setup wizard (step 7) or anytime via the CLI.
|
|
83
|
-
|
|
84
|
-
### Voice Messages
|
|
54
|
+
Pulls the latest image and restarts. Vault data is persisted and not affected.
|
|
85
55
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
```sh
|
|
89
|
-
npx limbo-ai@latest config voice --enable --api-key gsk_xxx
|
|
90
|
-
npx limbo-ai@latest config voice --status
|
|
91
|
-
npx limbo-ai@latest config voice --disable
|
|
92
|
-
```
|
|
56
|
+
---
|
|
93
57
|
|
|
94
|
-
|
|
58
|
+
## Local Install (macOS/Linux)
|
|
95
59
|
|
|
96
|
-
|
|
60
|
+
If you prefer running locally instead of a VPS:
|
|
97
61
|
|
|
98
|
-
```
|
|
99
|
-
npx limbo-ai
|
|
100
|
-
npx limbo-ai@latest config web-search --status
|
|
101
|
-
npx limbo-ai@latest config web-search --disable
|
|
62
|
+
```bash
|
|
63
|
+
npx limbo-ai start
|
|
102
64
|
```
|
|
103
65
|
|
|
104
|
-
|
|
66
|
+
Requires [Docker Desktop](https://docs.docker.com/get-docker/) and Node.js 18+. Binds to `127.0.0.1:18789`.
|
|
105
67
|
|
|
106
68
|
---
|
|
107
69
|
|
|
108
|
-
##
|
|
70
|
+
## Commands
|
|
109
71
|
|
|
110
72
|
```sh
|
|
111
|
-
|
|
73
|
+
limbo start # Install and start (enters wizard on first run)
|
|
74
|
+
limbo stop # Stop the container
|
|
75
|
+
limbo update # Pull latest image and restart
|
|
76
|
+
limbo status # Show container status
|
|
77
|
+
limbo logs # Tail container logs
|
|
78
|
+
limbo start --reconfigure # Re-run the setup wizard
|
|
79
|
+
limbo config voice --enable --api-key gsk_xxx # Enable voice transcription
|
|
80
|
+
limbo config web-search --enable --api-key BSA_xxx # Enable web search
|
|
112
81
|
```
|
|
113
82
|
|
|
114
|
-
Pulls the latest Limbo image and restarts the container. Your vault data is persisted in the `limbo-data` Docker volume and is not affected.
|
|
115
|
-
|
|
116
83
|
---
|
|
117
84
|
|
|
118
85
|
## Connecting
|
|
119
86
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
### Talk to Limbo
|
|
87
|
+
### Telegram (recommended)
|
|
123
88
|
|
|
124
|
-
|
|
89
|
+
The setup wizard walks you through creating a Telegram bot and pairing it. Message your bot and Limbo responds — full agent with personality, memory logic, and vault tools.
|
|
125
90
|
|
|
126
|
-
|
|
91
|
+
### ZeroClaw gateway
|
|
127
92
|
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
Any [ZeroClaw](https://github.com/zeroclaw-labs/zeroclaw)-compatible chat client can connect to:
|
|
93
|
+
Any [ZeroClaw](https://github.com/zeroclaw-labs/zeroclaw)-compatible client can connect via WebSocket:
|
|
131
94
|
|
|
132
95
|
```
|
|
133
96
|
ws://localhost:18789
|
|
134
97
|
```
|
|
135
98
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
### Use the vault from another agent
|
|
99
|
+
### MCP (for other AI agents)
|
|
139
100
|
|
|
140
|
-
|
|
101
|
+
Add Limbo as an MCP server to give another agent direct vault access:
|
|
141
102
|
|
|
142
103
|
```json
|
|
143
104
|
{
|
|
@@ -149,43 +110,43 @@ If you want another AI agent (like Claude Code) to read and write to Limbo's vau
|
|
|
149
110
|
}
|
|
150
111
|
```
|
|
151
112
|
|
|
152
|
-
This exposes
|
|
113
|
+
This exposes 4 vault tools (`vault_search`, `vault_read`, `vault_write_note`, `vault_update_map`). The connecting agent operates on the vault directly — Limbo's LLM is not involved.
|
|
153
114
|
|
|
154
115
|
---
|
|
155
116
|
|
|
156
|
-
##
|
|
117
|
+
## Optional Features
|
|
157
118
|
|
|
158
|
-
|
|
119
|
+
Enable during the setup wizard or anytime via CLI.
|
|
159
120
|
|
|
160
|
-
|
|
161
|
-
|----------|----------|---------|-------------|
|
|
162
|
-
| `AUTH_MODE` | no | `api-key` | `api-key` or `subscription` |
|
|
163
|
-
| `OPENAI_API_KEY` | no* | — | OpenAI API key for `MODEL_PROVIDER=openai` |
|
|
164
|
-
| `ANTHROPIC_API_KEY` | no* | — | Anthropic API key for `MODEL_PROVIDER=anthropic` |
|
|
165
|
-
| `LLM_API_KEY` | no | — | Legacy generic key path for older installs |
|
|
166
|
-
| `MODEL_PROVIDER` | no | `anthropic` | Model provider: `anthropic`, `openai`, or `openai-codex` |
|
|
167
|
-
| `MODEL_NAME` | no | `claude-opus-4-6` | Model name (e.g. `claude-opus-4-6`, `claude-sonnet-4-6`, `gpt-5.4`) |
|
|
168
|
-
| `TELEGRAM_ENABLED` | no | `false` | Enable Telegram bot integration |
|
|
169
|
-
| `TELEGRAM_BOT_TOKEN` | no | — | Telegram bot token (required if `TELEGRAM_ENABLED=true`) |
|
|
170
|
-
| `VOICE_ENABLED` | no | `false` | Enable voice transcription (requires Groq API key as Docker secret) |
|
|
171
|
-
| `WEB_SEARCH_ENABLED` | no | `false` | Enable web search (requires Brave API key as Docker secret) |
|
|
121
|
+
### Voice Messages
|
|
172
122
|
|
|
173
|
-
|
|
123
|
+
Transcribe Telegram voice notes using [Groq](https://groq.com) Whisper.
|
|
174
124
|
|
|
175
|
-
|
|
125
|
+
```sh
|
|
126
|
+
limbo config voice --enable --api-key gsk_xxx
|
|
127
|
+
limbo config voice --disable
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
### Web Search
|
|
176
131
|
|
|
177
|
-
|
|
132
|
+
Real-time web search via [Brave Search API](https://brave.com/search/api/).
|
|
178
133
|
|
|
179
|
-
|
|
134
|
+
```sh
|
|
135
|
+
limbo config web-search --enable --api-key BSAxxx
|
|
136
|
+
limbo config web-search --disable
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
---
|
|
180
140
|
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
|
184
|
-
|
|
185
|
-
|
|
|
186
|
-
|
|
|
141
|
+
## Hardware Requirements
|
|
142
|
+
|
|
143
|
+
| Tier | RAM | vCPU | Disk |
|
|
144
|
+
|------|-----|------|------|
|
|
145
|
+
| Minimum | 512 MB | 1 | 1 GB |
|
|
146
|
+
| Recommended | 1 GB | 1 | 5 GB |
|
|
147
|
+
| With other services | 2 GB | 1 | 10 GB |
|
|
187
148
|
|
|
188
|
-
|
|
149
|
+
Limbo uses ~35 MB at rest, peaks ~70 MB during cold starts. CPU usage is negligible.
|
|
189
150
|
|
|
190
151
|
---
|
|
191
152
|
|
|
@@ -211,54 +172,59 @@ Full tool specs in `workspace/TOOLS.md`.
|
|
|
211
172
|
└─────────────────────────────────────────┘
|
|
212
173
|
```
|
|
213
174
|
|
|
214
|
-
- **ZeroClaw** —
|
|
215
|
-
- **MCP server** — Node.js
|
|
216
|
-
- **Vault** — plain markdown
|
|
217
|
-
- **Migrations** — lightweight Node.js migration runner for vault schema changes
|
|
175
|
+
- **ZeroClaw** — Rust runtime (~5 MB RAM) handling connections, LLM routing, Telegram, and MCP tools
|
|
176
|
+
- **MCP server** — Node.js vault read/write tools, spawned by ZeroClaw
|
|
177
|
+
- **Vault** — plain markdown with YAML frontmatter, persisted in a Docker volume
|
|
218
178
|
|
|
219
|
-
|
|
179
|
+
---
|
|
220
180
|
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
memory/ # agent memory
|
|
228
|
-
config/
|
|
229
|
-
USER.md # per-user persona file (generated at runtime)
|
|
181
|
+
## Agent Installation (headless)
|
|
182
|
+
|
|
183
|
+
For CI/CD or automated provisioning:
|
|
184
|
+
|
|
185
|
+
```bash
|
|
186
|
+
npx limbo-ai start --provider anthropic --api-key sk-ant-xxx --model claude-sonnet-4-6
|
|
230
187
|
```
|
|
231
188
|
|
|
232
|
-
|
|
189
|
+
| Flag | Required | Default | Description |
|
|
190
|
+
|------|----------|---------|-------------|
|
|
191
|
+
| `--provider` | yes | — | `anthropic`, `openai`, or `openrouter` |
|
|
192
|
+
| `--api-key` | yes | — | Provider API key |
|
|
193
|
+
| `--model` | no | Provider default | Model name |
|
|
194
|
+
| `--language` | no | `en` | `en` or `es` |
|
|
233
195
|
|
|
234
|
-
|
|
196
|
+
Headless mode skips Telegram. Add it later with `limbo start --reconfigure`.
|
|
235
197
|
|
|
236
|
-
|
|
198
|
+
> Subscription auth (Claude Code, ChatGPT Plus) requires the interactive wizard.
|
|
237
199
|
|
|
238
|
-
|
|
239
|
-
- Node.js 22+ (for local MCP server dev)
|
|
200
|
+
---
|
|
240
201
|
|
|
241
|
-
|
|
202
|
+
## Environment Variables
|
|
242
203
|
|
|
243
|
-
|
|
244
|
-
cd mcp-server
|
|
245
|
-
npm install
|
|
246
|
-
VAULT_PATH=./dev-vault node index.js
|
|
247
|
-
```
|
|
204
|
+
Managed by `limbo start`, stored in `~/.limbo/.env`.
|
|
248
205
|
|
|
249
|
-
|
|
206
|
+
| Variable | Default | Description |
|
|
207
|
+
|----------|---------|-------------|
|
|
208
|
+
| `AUTH_MODE` | `api-key` | `api-key` or `subscription` |
|
|
209
|
+
| `MODEL_PROVIDER` | `anthropic` | `anthropic`, `openai`, `openai-codex`, or `openrouter` |
|
|
210
|
+
| `MODEL_NAME` | `claude-sonnet-4-6` | Model to use |
|
|
211
|
+
| `TELEGRAM_ENABLED` | `false` | Enable Telegram integration |
|
|
212
|
+
| `VOICE_ENABLED` | `false` | Enable Groq voice transcription |
|
|
213
|
+
| `WEB_SEARCH_ENABLED` | `false` | Enable Brave web search |
|
|
250
214
|
|
|
251
|
-
|
|
252
|
-
docker build -t limbo:dev .
|
|
253
|
-
docker compose up -d
|
|
254
|
-
```
|
|
215
|
+
---
|
|
255
216
|
|
|
256
|
-
|
|
217
|
+
## Development
|
|
257
218
|
|
|
258
219
|
```sh
|
|
259
|
-
|
|
260
|
-
|
|
220
|
+
# Run MCP server locally
|
|
221
|
+
cd mcp-server && npm install && VAULT_PATH=./dev-vault node index.js
|
|
261
222
|
|
|
262
|
-
|
|
223
|
+
# Build image locally
|
|
224
|
+
docker build -t limbo:dev . && docker compose up -d
|
|
225
|
+
|
|
226
|
+
# Run tests
|
|
227
|
+
npm test
|
|
228
|
+
```
|
|
263
229
|
|
|
264
230
|
See [CONTRIBUTING.md](./CONTRIBUTING.md) for release and deployment process.
|
package/package.json
CHANGED
package/setup-server/server.js
CHANGED
|
@@ -229,9 +229,11 @@ function decodeJwtPayload(token) {
|
|
|
229
229
|
return JSON.parse(Buffer.from(parts[1], 'base64url').toString());
|
|
230
230
|
}
|
|
231
231
|
|
|
232
|
-
//
|
|
233
|
-
//
|
|
234
|
-
//
|
|
232
|
+
// ─── OpenAI Codex auth profiles ──────────────────────────────────────────────
|
|
233
|
+
// OpenAI OAuth tokens expire and need refresh. ZeroClaw reads auth-profiles.json
|
|
234
|
+
// for the refresh token and handles renewal automatically. This is ONLY needed
|
|
235
|
+
// for OpenAI Codex — Anthropic tokens are static and stored as secrets instead.
|
|
236
|
+
const AUTH_PROFILES_FILE = path.join(ZEROCLAW_STATE, 'auth-profiles.json');
|
|
235
237
|
|
|
236
238
|
function buildCodexAuthProfile(profile) {
|
|
237
239
|
const profileId = profile.email ? `openai-codex:${profile.email}` : 'openai-codex:default';
|
|
@@ -253,26 +255,6 @@ function buildCodexAuthProfile(profile) {
|
|
|
253
255
|
};
|
|
254
256
|
}
|
|
255
257
|
|
|
256
|
-
function buildAnthropicAuthProfile(token) {
|
|
257
|
-
return {
|
|
258
|
-
version: 1,
|
|
259
|
-
profiles: {
|
|
260
|
-
'anthropic:token': {
|
|
261
|
-
type: 'token',
|
|
262
|
-
provider: 'anthropic',
|
|
263
|
-
token,
|
|
264
|
-
},
|
|
265
|
-
},
|
|
266
|
-
order: { anthropic: ['anthropic:token'] },
|
|
267
|
-
lastGood: {},
|
|
268
|
-
usageStats: {},
|
|
269
|
-
};
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
// ZeroClaw resolves auth profiles from the state dir root: ~/.zeroclaw/auth-profiles.json
|
|
273
|
-
// See: ZeroClaw src/auth/profiles.rs — state_dir.join("auth-profiles.json")
|
|
274
|
-
const AUTH_PROFILES_FILE = path.join(ZEROCLAW_STATE, 'auth-profiles.json');
|
|
275
|
-
|
|
276
258
|
function writeAuthProfiles(store) {
|
|
277
259
|
fs.mkdirSync(ZEROCLAW_STATE, { recursive: true, mode: 0o700 });
|
|
278
260
|
fs.writeFileSync(AUTH_PROFILES_FILE, JSON.stringify(store, null, 2), { mode: 0o600 });
|
|
@@ -557,6 +539,7 @@ async function exchangeOAuthCode(code, verifier, redirectUri) {
|
|
|
557
539
|
function processOAuthTokens(tokenRes) {
|
|
558
540
|
const jwt = decodeJwtPayload(tokenRes.access_token);
|
|
559
541
|
const authClaim = jwt['https://api.openai.com/auth'] || {};
|
|
542
|
+
// Write auth profile for ZeroClaw's OAuth refresh flow
|
|
560
543
|
const store = buildCodexAuthProfile({
|
|
561
544
|
access: tokenRes.access_token,
|
|
562
545
|
refresh: tokenRes.refresh_token,
|
|
@@ -565,6 +548,8 @@ function processOAuthTokens(tokenRes) {
|
|
|
565
548
|
email: jwt.email || '',
|
|
566
549
|
});
|
|
567
550
|
writeAuthProfiles(store);
|
|
551
|
+
// Also write access token as secret for entrypoint to export
|
|
552
|
+
writeSecretFile('llm_api_key', tokenRes.access_token);
|
|
568
553
|
return { email: jwt.email || '' };
|
|
569
554
|
}
|
|
570
555
|
|
|
@@ -676,8 +661,9 @@ async function handleAnthropicToken(req, res) {
|
|
|
676
661
|
return;
|
|
677
662
|
}
|
|
678
663
|
|
|
679
|
-
|
|
680
|
-
|
|
664
|
+
// Anthropic tokens are static (no refresh needed) — store as secret
|
|
665
|
+
writeSecretFile('llm_api_key', token);
|
|
666
|
+
log('Anthropic token written to secrets/llm_api_key');
|
|
681
667
|
sendJSON(res, 200, { success: true });
|
|
682
668
|
}
|
|
683
669
|
|
|
@@ -861,7 +847,6 @@ module.exports = {
|
|
|
861
847
|
buildOAuthUrl,
|
|
862
848
|
decodeJwtPayload,
|
|
863
849
|
buildCodexAuthProfile,
|
|
864
|
-
buildAnthropicAuthProfile,
|
|
865
850
|
handleRequest,
|
|
866
851
|
_internals: {
|
|
867
852
|
OPENAI_OAUTH,
|
|
@@ -15,7 +15,6 @@ const {
|
|
|
15
15
|
buildOAuthUrl,
|
|
16
16
|
decodeJwtPayload,
|
|
17
17
|
buildCodexAuthProfile,
|
|
18
|
-
buildAnthropicAuthProfile,
|
|
19
18
|
handleRequest,
|
|
20
19
|
_internals: { OPENAI_OAUTH },
|
|
21
20
|
} = require('../setup-server/server.js');
|
|
@@ -197,24 +196,6 @@ describe('buildCodexAuthProfile', () => {
|
|
|
197
196
|
});
|
|
198
197
|
});
|
|
199
198
|
|
|
200
|
-
describe('buildAnthropicAuthProfile', () => {
|
|
201
|
-
it('builds correct structure', () => {
|
|
202
|
-
const result = buildAnthropicAuthProfile('sk-ant-test123');
|
|
203
|
-
assert.strictEqual(result.version, 1);
|
|
204
|
-
const pid = 'anthropic:token';
|
|
205
|
-
assert.ok(result.profiles[pid], 'profile entry exists');
|
|
206
|
-
assert.strictEqual(result.profiles[pid].provider, 'anthropic');
|
|
207
|
-
assert.strictEqual(result.profiles[pid].type, 'token');
|
|
208
|
-
assert.strictEqual(result.profiles[pid].token, 'sk-ant-test123');
|
|
209
|
-
});
|
|
210
|
-
|
|
211
|
-
it('order includes anthropic key', () => {
|
|
212
|
-
const result = buildAnthropicAuthProfile('sk-ant-xyz');
|
|
213
|
-
assert.ok(result.order.anthropic, 'order has anthropic key');
|
|
214
|
-
assert.deepStrictEqual(result.order.anthropic, ['anthropic:token']);
|
|
215
|
-
});
|
|
216
|
-
});
|
|
217
|
-
|
|
218
199
|
// ─── B. HTTP handler tests ──────────────────────────────────────────────────
|
|
219
200
|
|
|
220
201
|
describe('HTTP handler', () => {
|