hoomanjs 1.33.0 → 1.35.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/README.md +114 -270
- package/dist/acp/acp-agent.js +2 -16
- package/dist/acp/acp-agent.js.map +1 -1
- package/dist/acp/sessions/options.js +2 -2
- package/dist/acp/sessions/options.js.map +1 -1
- package/dist/acp/sessions/store.d.ts +0 -2
- package/dist/acp/sessions/store.js.map +1 -1
- package/dist/acp/utils/tool-kind.js +10 -2
- package/dist/acp/utils/tool-kind.js.map +1 -1
- package/dist/chat/app.d.ts +2 -1
- package/dist/chat/app.js +94 -23
- package/dist/chat/app.js.map +1 -1
- package/dist/chat/components/BottomChrome.d.ts +6 -2
- package/dist/chat/components/BottomChrome.js +2 -2
- package/dist/chat/components/BottomChrome.js.map +1 -1
- package/dist/chat/components/ChromePicker.d.ts +7 -2
- package/dist/chat/components/ChromePicker.js +9 -2
- package/dist/chat/components/ChromePicker.js.map +1 -1
- package/dist/chat/components/StatusBar.d.ts +1 -2
- package/dist/chat/components/StatusBar.js +3 -12
- package/dist/chat/components/StatusBar.js.map +1 -1
- package/dist/chat/components/ToolEvent.js +1 -1
- package/dist/chat/components/ToolEvent.js.map +1 -1
- package/dist/chat/index.d.ts +2 -1
- package/dist/chat/index.js +7 -0
- package/dist/chat/index.js.map +1 -1
- package/dist/cli.js +120 -4
- package/dist/cli.js.map +1 -1
- package/dist/configure/app.js +1005 -392
- package/dist/configure/app.js.map +1 -1
- package/dist/configure/index.js.map +1 -1
- package/dist/configure/types.d.ts +18 -0
- package/dist/core/agent/index.d.ts +13 -3
- package/dist/core/agent/index.js +83 -15
- package/dist/core/agent/index.js.map +1 -1
- package/dist/core/config.d.ts +319 -87
- package/dist/core/config.js +191 -218
- package/dist/core/config.js.map +1 -1
- package/dist/core/index.d.ts +1 -2
- package/dist/core/index.js +6 -7
- package/dist/core/index.js.map +1 -1
- package/dist/core/mcp/config.d.ts +7 -1
- package/dist/core/mcp/config.js +41 -8
- package/dist/core/mcp/config.js.map +1 -1
- package/dist/core/mcp/manager.js +1 -1
- package/dist/core/mcp/manager.js.map +1 -1
- package/dist/core/mcp/oauth/provider.js.map +1 -1
- package/dist/core/mcp/prefixed-mcp-tool.d.ts +0 -1
- package/dist/core/mcp/prefixed-mcp-tool.js +0 -2
- package/dist/core/mcp/prefixed-mcp-tool.js.map +1 -1
- package/dist/core/memory/index.d.ts +1 -0
- package/dist/core/memory/index.js +1 -0
- package/dist/core/memory/index.js.map +1 -1
- package/dist/core/memory/model-extractor.js.map +1 -0
- package/dist/core/models/anthropic.d.ts +3 -12
- package/dist/core/models/anthropic.js +20 -91
- package/dist/core/models/anthropic.js.map +1 -1
- package/dist/core/models/azure.d.ts +4 -0
- package/dist/core/models/azure.js +26 -0
- package/dist/core/models/azure.js.map +1 -0
- package/dist/core/models/bedrock.d.ts +3 -20
- package/dist/core/models/bedrock.js +22 -18
- package/dist/core/models/bedrock.js.map +1 -1
- package/dist/core/models/google.d.ts +2 -9
- package/dist/core/models/google.js +12 -31
- package/dist/core/models/google.js.map +1 -1
- package/dist/core/models/groq.d.ts +2 -9
- package/dist/core/models/groq.js +15 -25
- package/dist/core/models/groq.js.map +1 -1
- package/dist/core/models/index.d.ts +2 -1
- package/dist/core/models/index.js +3 -0
- package/dist/core/models/index.js.map +1 -1
- package/dist/core/models/minimax.d.ts +2 -0
- package/dist/core/models/minimax.js +11 -0
- package/dist/core/models/minimax.js.map +1 -0
- package/dist/core/models/moonshot.d.ts +2 -10
- package/dist/core/models/moonshot.js +23 -38
- package/dist/core/models/moonshot.js.map +1 -1
- package/dist/core/models/ollama/index.d.ts +2 -1
- package/dist/core/models/ollama/index.js +12 -5
- package/dist/core/models/ollama/index.js.map +1 -1
- package/dist/core/models/openai.d.ts +3 -4
- package/dist/core/models/openai.js +20 -3
- package/dist/core/models/openai.js.map +1 -1
- package/dist/core/models/openrouter.d.ts +4 -0
- package/dist/core/models/openrouter.js +23 -0
- package/dist/core/models/openrouter.js.map +1 -0
- package/dist/core/models/types.d.ts +346 -0
- package/dist/core/models/types.js +220 -0
- package/dist/core/models/types.js.map +1 -0
- package/dist/core/models/xai.d.ts +2 -9
- package/dist/core/models/xai.js +15 -25
- package/dist/core/models/xai.js.map +1 -1
- package/dist/core/modes/definitions.js +6 -2
- package/dist/core/modes/definitions.js.map +1 -1
- package/dist/core/prompts/agents/research.md +8 -4
- package/dist/core/prompts/agents/review.md +26 -0
- package/dist/core/prompts/agents/test-investigator.md +26 -0
- package/dist/core/prompts/modes/ask.md +1 -1
- package/dist/core/prompts/modes/plan.md +1 -1
- package/dist/core/prompts/runtime.js +2 -30
- package/dist/core/prompts/runtime.js.map +1 -1
- package/dist/core/prompts/static/subagents.md +12 -8
- package/dist/core/prompts/system.js +1 -1
- package/dist/core/prompts/system.js.map +1 -1
- package/dist/core/runtime-config.d.ts +16 -0
- package/dist/core/runtime-config.js +44 -0
- package/dist/core/runtime-config.js.map +1 -0
- package/dist/core/session-config.js +2 -1
- package/dist/core/session-config.js.map +1 -1
- package/dist/core/sessions/flat-file-storage.js.map +1 -0
- package/dist/core/sessions/lazy-session-manager.js.map +1 -0
- package/dist/core/sessions/list-cli-sessions.d.ts +12 -0
- package/dist/core/sessions/list-cli-sessions.js +174 -0
- package/dist/core/sessions/list-cli-sessions.js.map +1 -0
- package/dist/core/skills/built-in/hooman-config/SKILL.md +98 -201
- package/dist/core/state/tool-approvals.js +4 -3
- package/dist/core/state/tool-approvals.js.map +1 -1
- package/dist/core/subagents/index.d.ts +2 -3
- package/dist/core/subagents/index.js +2 -3
- package/dist/core/subagents/index.js.map +1 -1
- package/dist/core/subagents/registry.d.ts +22 -0
- package/dist/core/subagents/registry.js +96 -0
- package/dist/core/subagents/registry.js.map +1 -0
- package/dist/core/subagents/tool.d.ts +6 -14
- package/dist/core/subagents/tool.js +73 -53
- package/dist/core/subagents/tool.js.map +1 -1
- package/dist/core/tools/filesystem.js +2 -9
- package/dist/core/tools/filesystem.js.map +1 -1
- package/dist/core/tools/shell.js.map +1 -1
- package/dist/core/utils/discover-files.d.ts +12 -0
- package/dist/core/utils/discover-files.js +47 -0
- package/dist/core/utils/discover-files.js.map +1 -0
- package/dist/index.d.ts +8 -5
- package/dist/index.js +7 -3
- package/dist/index.js.map +1 -1
- package/package.json +2 -1
- package/dist/acp/meta/system-prompt.d.ts +0 -12
- package/dist/acp/meta/system-prompt.js +0 -41
- package/dist/acp/meta/system-prompt.js.map +0 -1
- package/dist/core/context/flat-file-storage.js.map +0 -1
- package/dist/core/context/index.d.ts +0 -22
- package/dist/core/context/index.js +0 -74
- package/dist/core/context/index.js.map +0 -1
- package/dist/core/context/lazy-session-manager.js.map +0 -1
- package/dist/core/context/model-extractor.js.map +0 -1
- package/dist/core/subagents/research.d.ts +0 -16
- package/dist/core/subagents/research.js +0 -58
- package/dist/core/subagents/research.js.map +0 -1
- package/dist/core/subagents/runner.d.ts +0 -37
- package/dist/core/subagents/runner.js +0 -273
- package/dist/core/subagents/runner.js.map +0 -1
- /package/dist/core/{context → memory}/model-extractor.d.ts +0 -0
- /package/dist/core/{context → memory}/model-extractor.js +0 -0
- /package/dist/core/{context → sessions}/flat-file-storage.d.ts +0 -0
- /package/dist/core/{context → sessions}/flat-file-storage.js +0 -0
- /package/dist/core/{context → sessions}/lazy-session-manager.d.ts +0 -0
- /package/dist/core/{context → sessions}/lazy-session-manager.js +0 -0
package/README.md
CHANGED
|
@@ -21,7 +21,7 @@ It gives you a practical toolkit to build and run agent workflows:
|
|
|
21
21
|
- a one-shot `exec` command for single prompts
|
|
22
22
|
- a stateful `chat` interface for iterative sessions
|
|
23
23
|
- a `daemon` command for channel-driven MCP automation
|
|
24
|
-
- an in-chat `/config` workflow (Ink-powered) for
|
|
24
|
+
- an in-chat `/config` workflow (Ink-powered) for general settings, models, MCP servers, and installed skills
|
|
25
25
|
- an `acp` command for running Hooman as an Agent Client Protocol (ACP) agent over stdio
|
|
26
26
|
|
|
27
27
|
## Related
|
|
@@ -30,7 +30,7 @@ It gives you a practical toolkit to build and run agent workflows:
|
|
|
30
30
|
|
|
31
31
|
## Features
|
|
32
32
|
|
|
33
|
-
- Multiple LLM providers: `anthropic`, `bedrock`, `google`, `groq`, `moonshot`, `ollama`, `openai`, `xai`
|
|
33
|
+
- Multiple LLM providers: `anthropic`, `azure`, `bedrock`, `google`, `groq`, `minimax`, `moonshot`, `ollama`, `openai`, `openrouter`, `xai`
|
|
34
34
|
- Local configuration under `~/.hooman`
|
|
35
35
|
- Optional web search tool with provider selection (`brave`, `exa`, `firecrawl`, `serper`, or `tavily`)
|
|
36
36
|
- MCP server support via `stdio`, `streamable-http`, and `sse`
|
|
@@ -38,7 +38,7 @@ It gives you a practical toolkit to build and run agent workflows:
|
|
|
38
38
|
- MCP channel notifications: `hooman daemon` subscribes to servers that advertise `hooman/channel`
|
|
39
39
|
- Runtime skills via Strands `AgentSkills`, loading bundled built-in skills plus local `~/.hooman/skills`
|
|
40
40
|
- Bundled prompt harness toggles (`behaviour`, `communication`, `execution`, `guardrails`); coding guidance ships as the built-in `hooman-coding` skill
|
|
41
|
-
- Built-in
|
|
41
|
+
- Built-in read-only subagent tools (`subagent_research`, `subagent_review`, `subagent_test_investigator`)
|
|
42
42
|
- Built-in `grep` tool backed by ripgrep (`rg`), with runtime bootstrap when `rg` is not available on PATH
|
|
43
43
|
- Toolkit-oriented architecture with configurable tools, prompts, and transports
|
|
44
44
|
- Interactive terminal UI for chat and configuration
|
|
@@ -231,6 +231,15 @@ Log raw notification payloads:
|
|
|
231
231
|
hooman daemon --debug
|
|
232
232
|
```
|
|
233
233
|
|
|
234
|
+
### `hooman config`
|
|
235
|
+
|
|
236
|
+
Print the effective runtime `config.json` for the current working directory in
|
|
237
|
+
the same shape as `config.json`, with credential-like values redacted.
|
|
238
|
+
|
|
239
|
+
```bash
|
|
240
|
+
hooman config
|
|
241
|
+
```
|
|
242
|
+
|
|
234
243
|
### Feature Flags
|
|
235
244
|
|
|
236
245
|
Runtime tool and prompt switches are controlled from `config.json`:
|
|
@@ -251,12 +260,11 @@ Runtime tool and prompt switches are controlled from `config.json`:
|
|
|
251
260
|
- `tools.filesystem.enabled`
|
|
252
261
|
- `tools.shell.enabled`
|
|
253
262
|
- `tools.sleep.enabled`
|
|
254
|
-
- `tools.
|
|
255
|
-
- `tools.agents.concurrency` (defaults to `3` when omitted on load; a freshly generated default `config.json` uses `2`)
|
|
263
|
+
- `tools.subagents.enabled` (enables built-in subagent tools)
|
|
256
264
|
|
|
257
265
|
### `/config`
|
|
258
266
|
|
|
259
|
-
The configuration workflow is launched from inside a `chat` session with the `/config` slash command (there is no separate top-level `configure` command). It takes over the terminal on the alternate screen buffer while open, and restores the chat session on exit. Any config changes are picked up when the session re-bootstraps.
|
|
267
|
+
The interactive configuration workflow is launched from inside a `chat` session with the `/config` slash command (there is no separate top-level `configure` command). It takes over the terminal on the alternate screen buffer while open, and restores the chat session on exit. Any config changes are picked up when the session re-bootstraps.
|
|
260
268
|
|
|
261
269
|
```text
|
|
262
270
|
/config
|
|
@@ -264,11 +272,12 @@ The configuration workflow is launched from inside a `chat` session with the `/c
|
|
|
264
272
|
|
|
265
273
|
The configuration UI currently lets you:
|
|
266
274
|
|
|
267
|
-
-
|
|
275
|
+
- manage general settings such as name, prompts, tools, and compaction
|
|
276
|
+
- manage models and providers with field-by-field editors
|
|
268
277
|
- choose search provider and set its API key
|
|
269
278
|
- toggle bundled harness prompts (`behaviour`, `communication`, `execution`, `guardrails`)
|
|
270
279
|
- edit `instructions.md` in your `$VISUAL` / `$EDITOR` (cross-platform fallback included)
|
|
271
|
-
- add, edit, and delete MCP servers with confirmation
|
|
280
|
+
- add, edit, and delete MCP servers with field-by-field editors and confirmation
|
|
272
281
|
- search, install, refresh, and remove skills
|
|
273
282
|
|
|
274
283
|
### `hooman acp`
|
|
@@ -283,8 +292,7 @@ ACP notes:
|
|
|
283
292
|
|
|
284
293
|
- ACP sessions are stored under the active Hooman data directory in `acp-sessions/`
|
|
285
294
|
- ACP loads MCP servers passed on `session/new` and `session/load`, in addition to Hooman's local `mcp.json`
|
|
286
|
-
- ACP `session/new` and `session/load` support `_meta.userId`
|
|
287
|
-
- when `_meta.systemPrompt` is provided, it is appended to the agent system prompt with a section break
|
|
295
|
+
- ACP `session/new` and `session/load` support `_meta.userId`
|
|
288
296
|
- session configuration includes `hooman.sessionMode` (`agent`, `plan`, or `ask`); see [Session mode](#session-mode)
|
|
289
297
|
|
|
290
298
|
## Configuration Layout
|
|
@@ -306,6 +314,33 @@ Important files and folders:
|
|
|
306
314
|
- `sessions/` - persisted session data
|
|
307
315
|
- `acp-sessions/` - persisted ACP session metadata and message snapshots
|
|
308
316
|
|
|
317
|
+
### Repo-local runtime overlays
|
|
318
|
+
|
|
319
|
+
At runtime, Hooman resolves configuration in this order:
|
|
320
|
+
|
|
321
|
+
1. `~/.hooman/config.json` and `~/.hooman/mcp.json`
|
|
322
|
+
2. `<git-root>/config.json` and `<git-root>/mcp.json` (if present)
|
|
323
|
+
3. matching files in nested directories from git root to current working directory
|
|
324
|
+
|
|
325
|
+
Nearest files win when keys overlap.
|
|
326
|
+
|
|
327
|
+
For app config (`config.json`):
|
|
328
|
+
|
|
329
|
+
- plain objects are deep-merged
|
|
330
|
+
- scalar values are overridden by the nearest file
|
|
331
|
+
- `providers` and `llms` are merged by `name` (nearest entry with the same name replaces inherited entries)
|
|
332
|
+
|
|
333
|
+
For MCP config (`mcp.json`):
|
|
334
|
+
|
|
335
|
+
- `mcpServers` is merged by server name (nearest entry with the same name wins)
|
|
336
|
+
|
|
337
|
+
Notes:
|
|
338
|
+
|
|
339
|
+
- Runtime overlays apply to `chat`, `exec`, `daemon`, and `acp` bootstraps.
|
|
340
|
+
- `hooman config` prints only the merged effective `config.json` shape with credential-like values redacted.
|
|
341
|
+
- The `/config` UI and `hooman mcp auth/logout/auth-status` still target home config (`~/.hooman/*`) directly.
|
|
342
|
+
- Keep secrets in home config unless you explicitly want project-scoped credentials.
|
|
343
|
+
|
|
309
344
|
`grep` tool binary resolution order:
|
|
310
345
|
|
|
311
346
|
1. Use system `rg` when available.
|
|
@@ -314,27 +349,24 @@ Important files and folders:
|
|
|
314
349
|
|
|
315
350
|
## Example `config.json`
|
|
316
351
|
|
|
317
|
-
The on-disk shape uses a reusable **`providers`** array plus a non-empty **`llms`** array. Each provider stores
|
|
352
|
+
The on-disk shape uses a reusable **`providers`** array plus a non-empty **`llms`** array. Each provider stores a runtime `provider` id plus provider-specific `options`; each LLM references a provider by name, stores its model `options`, and marks one entry as the default. The bundled **hooman-config** skill documents the full schema.
|
|
318
353
|
|
|
319
354
|
```json
|
|
320
355
|
{
|
|
321
356
|
"name": "Hooman",
|
|
322
357
|
"providers": [
|
|
323
358
|
{
|
|
324
|
-
"name": "
|
|
325
|
-
"
|
|
326
|
-
|
|
327
|
-
"params": {}
|
|
328
|
-
}
|
|
359
|
+
"name": "Ollama",
|
|
360
|
+
"provider": "ollama",
|
|
361
|
+
"options": {}
|
|
329
362
|
}
|
|
330
363
|
],
|
|
331
364
|
"llms": [
|
|
332
365
|
{
|
|
333
366
|
"name": "Default",
|
|
367
|
+
"provider": "Ollama",
|
|
334
368
|
"options": {
|
|
335
|
-
"
|
|
336
|
-
"model": "gemma4:e4b",
|
|
337
|
-
"params": {}
|
|
369
|
+
"model": "gemma4:e4b"
|
|
338
370
|
},
|
|
339
371
|
"default": true
|
|
340
372
|
}
|
|
@@ -355,25 +387,12 @@ The on-disk shape uses a reusable **`providers`** array plus a non-empty **`llms
|
|
|
355
387
|
"guardrails": true
|
|
356
388
|
},
|
|
357
389
|
"tools": {
|
|
358
|
-
"todo": {
|
|
359
|
-
|
|
360
|
-
},
|
|
361
|
-
"
|
|
362
|
-
|
|
363
|
-
}
|
|
364
|
-
"filesystem": {
|
|
365
|
-
"enabled": true
|
|
366
|
-
},
|
|
367
|
-
"shell": {
|
|
368
|
-
"enabled": true
|
|
369
|
-
},
|
|
370
|
-
"sleep": {
|
|
371
|
-
"enabled": true
|
|
372
|
-
},
|
|
373
|
-
"agents": {
|
|
374
|
-
"enabled": true,
|
|
375
|
-
"concurrency": 2
|
|
376
|
-
}
|
|
390
|
+
"todo": { "enabled": true },
|
|
391
|
+
"fetch": { "enabled": true },
|
|
392
|
+
"filesystem": { "enabled": true },
|
|
393
|
+
"shell": { "enabled": true },
|
|
394
|
+
"sleep": { "enabled": true },
|
|
395
|
+
"subagents": { "enabled": true }
|
|
377
396
|
},
|
|
378
397
|
"compaction": {
|
|
379
398
|
"ratio": 0.75,
|
|
@@ -386,19 +405,20 @@ Tool approvals are session-scoped and are not persisted in `config.json`.
|
|
|
386
405
|
|
|
387
406
|
Hooman enables Strands `ContextOffloader` by default with file-backed storage under `~/.hooman/sessions/offloaded-content`, so large tool results can be previewed in-context and retrieved later without bloating the active conversation window.
|
|
388
407
|
|
|
389
|
-
Supported `providers[].
|
|
408
|
+
Supported `providers[].provider` values registered in this release (see `src/core/models/index.ts`):
|
|
390
409
|
|
|
391
410
|
- `anthropic`
|
|
411
|
+
- `azure`
|
|
392
412
|
- `bedrock`
|
|
393
413
|
- `google`
|
|
394
414
|
- `groq`
|
|
415
|
+
- `minimax`
|
|
395
416
|
- `moonshot`
|
|
396
417
|
- `ollama`
|
|
397
418
|
- `openai`
|
|
419
|
+
- `openrouter`
|
|
398
420
|
- `xai`
|
|
399
421
|
|
|
400
|
-
The `LlmProvider` enum in `src/core/config.ts` may list additional strings for forwards compatibility; unknown providers are not loaded at runtime.
|
|
401
|
-
|
|
402
422
|
Supported `search.provider` values:
|
|
403
423
|
|
|
404
424
|
- `brave`
|
|
@@ -409,253 +429,62 @@ Supported `search.provider` values:
|
|
|
409
429
|
|
|
410
430
|
## Provider Notes
|
|
411
431
|
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
Good default for local usage. Example:
|
|
415
|
-
|
|
416
|
-
```json
|
|
417
|
-
{
|
|
418
|
-
"providers": [
|
|
419
|
-
{
|
|
420
|
-
"name": "ollama-local",
|
|
421
|
-
"options": {
|
|
422
|
-
"provider": "ollama",
|
|
423
|
-
"params": {}
|
|
424
|
-
}
|
|
425
|
-
}
|
|
426
|
-
],
|
|
427
|
-
"llms": [
|
|
428
|
-
{
|
|
429
|
-
"name": "Default",
|
|
430
|
-
"options": {
|
|
431
|
-
"provider": "ollama-local",
|
|
432
|
-
"model": "gemma4:e4b",
|
|
433
|
-
"params": {}
|
|
434
|
-
},
|
|
435
|
-
"default": true
|
|
436
|
-
}
|
|
437
|
-
]
|
|
438
|
-
}
|
|
439
|
-
```
|
|
440
|
-
|
|
441
|
-
### OpenAI
|
|
442
|
-
|
|
443
|
-
Uses Strands **OpenAIModel** (Chat Completions). `apiKey` is optional if `OPENAI_API_KEY` is set. Use `clientConfig` for a custom base URL or other OpenAI client options (OpenAI-compatible proxies and gateways).
|
|
444
|
-
|
|
445
|
-
Example:
|
|
446
|
-
|
|
447
|
-
```json
|
|
448
|
-
{
|
|
449
|
-
"providers": [
|
|
450
|
-
{
|
|
451
|
-
"name": "openai",
|
|
452
|
-
"options": {
|
|
453
|
-
"provider": "openai",
|
|
454
|
-
"params": {
|
|
455
|
-
"apiKey": "..."
|
|
456
|
-
}
|
|
457
|
-
}
|
|
458
|
-
}
|
|
459
|
-
],
|
|
460
|
-
"llms": [
|
|
461
|
-
{
|
|
462
|
-
"name": "GPT-5",
|
|
463
|
-
"options": {
|
|
464
|
-
"provider": "openai",
|
|
465
|
-
"model": "gpt-5",
|
|
466
|
-
"params": {}
|
|
467
|
-
},
|
|
468
|
-
"default": true
|
|
469
|
-
}
|
|
470
|
-
]
|
|
471
|
-
}
|
|
472
|
-
```
|
|
473
|
-
|
|
474
|
-
OpenAI-compatible gateways that put token `usage` on the last streamed chunk together with `choices` are handled via a small stream shim so usage still surfaces in the UI.
|
|
475
|
-
|
|
476
|
-
### Anthropic
|
|
477
|
-
|
|
478
|
-
Uses Strands **AnthropicModel** (Anthropic Messages API). `apiKey` or `authToken`, optional `baseURL` and `headers` (merged into `clientConfig`), optional `clientConfig`, and model fields such as `temperature` and `maxTokens`. A prebuilt `client` is not configurable from JSON.
|
|
479
|
-
|
|
480
|
-
```json
|
|
481
|
-
{
|
|
482
|
-
"providers": [
|
|
483
|
-
{
|
|
484
|
-
"name": "anthropic",
|
|
485
|
-
"options": {
|
|
486
|
-
"provider": "anthropic",
|
|
487
|
-
"params": {
|
|
488
|
-
"apiKey": "..."
|
|
489
|
-
}
|
|
490
|
-
}
|
|
491
|
-
}
|
|
492
|
-
],
|
|
493
|
-
"llms": [
|
|
494
|
-
{
|
|
495
|
-
"name": "Claude Sonnet",
|
|
496
|
-
"options": {
|
|
497
|
-
"provider": "anthropic",
|
|
498
|
-
"model": "claude-sonnet-4-20250514",
|
|
499
|
-
"params": {
|
|
500
|
-
"temperature": 0.7
|
|
501
|
-
}
|
|
502
|
-
},
|
|
503
|
-
"default": true
|
|
504
|
-
}
|
|
505
|
-
]
|
|
506
|
-
}
|
|
507
|
-
```
|
|
508
|
-
|
|
509
|
-
### Google
|
|
510
|
-
|
|
511
|
-
Uses Strands `GoogleModel` on top of `@google/genai`. Top-level options like `apiKey`, `client`, `clientConfig`, and `builtInTools` are supported; other values go into Google generation params.
|
|
512
|
-
|
|
513
|
-
```json
|
|
514
|
-
{
|
|
515
|
-
"providers": [
|
|
516
|
-
{
|
|
517
|
-
"name": "google",
|
|
518
|
-
"options": {
|
|
519
|
-
"provider": "google",
|
|
520
|
-
"params": {
|
|
521
|
-
"apiKey": "..."
|
|
522
|
-
}
|
|
523
|
-
}
|
|
524
|
-
}
|
|
525
|
-
],
|
|
526
|
-
"llms": [
|
|
527
|
-
{
|
|
528
|
-
"name": "Gemini Flash",
|
|
529
|
-
"options": {
|
|
530
|
-
"provider": "google",
|
|
531
|
-
"model": "gemini-2.5-flash",
|
|
532
|
-
"params": {
|
|
533
|
-
"temperature": 0.7,
|
|
534
|
-
"maxOutputTokens": 2048,
|
|
535
|
-
"topP": 0.9,
|
|
536
|
-
"topK": 40
|
|
537
|
-
}
|
|
538
|
-
},
|
|
539
|
-
"default": true
|
|
540
|
-
}
|
|
541
|
-
]
|
|
542
|
-
}
|
|
543
|
-
```
|
|
544
|
-
|
|
545
|
-
### Bedrock
|
|
546
|
-
|
|
547
|
-
Supports `region`, `clientConfig`, and optional `apiKey`, with all other values forwarded as Bedrock model options.
|
|
548
|
-
|
|
549
|
-
```json
|
|
550
|
-
{
|
|
551
|
-
"providers": [
|
|
552
|
-
{
|
|
553
|
-
"name": "bedrock-dev",
|
|
554
|
-
"options": {
|
|
555
|
-
"provider": "bedrock",
|
|
556
|
-
"params": {
|
|
557
|
-
"region": "us-east-1",
|
|
558
|
-
"clientConfig": {
|
|
559
|
-
"profile": "dev",
|
|
560
|
-
"maxAttempts": 3,
|
|
561
|
-
"credentials": {
|
|
562
|
-
"accessKeyId": "AKIA...",
|
|
563
|
-
"secretAccessKey": "...",
|
|
564
|
-
"sessionToken": "..."
|
|
565
|
-
}
|
|
566
|
-
}
|
|
567
|
-
}
|
|
568
|
-
}
|
|
569
|
-
}
|
|
570
|
-
],
|
|
571
|
-
"llms": [
|
|
572
|
-
{
|
|
573
|
-
"name": "Claude Sonnet",
|
|
574
|
-
"options": {
|
|
575
|
-
"provider": "bedrock-dev",
|
|
576
|
-
"model": "anthropic.claude-sonnet-4-20250514-v1:0",
|
|
577
|
-
"params": {
|
|
578
|
-
"temperature": 0.7,
|
|
579
|
-
"maxTokens": 1024
|
|
580
|
-
}
|
|
581
|
-
},
|
|
582
|
-
"default": true
|
|
583
|
-
}
|
|
584
|
-
]
|
|
585
|
-
}
|
|
586
|
-
```
|
|
587
|
-
|
|
588
|
-
You can also rely on the AWS default credential chain (recommended) by setting environment variables such as `AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY`, and optionally `AWS_SESSION_TOKEN`.
|
|
589
|
-
|
|
590
|
-
### Groq
|
|
591
|
-
|
|
592
|
-
### Anthropic
|
|
593
|
-
|
|
594
|
-
Uses Strands `AnthropicModel` on top of `@anthropic-ai/sdk`. Provider-specific settings `apiKey`/`authToken`, `baseURL`, `headers`, `clientConfig`, `betas`, and `useNativeTokenCount` are picked up directly. Standard model config such as `temperature`, `topP`, `maxTokens`, and `stopSequences` stays top-level. Any other keys are forwarded to the Anthropic Messages request body, which is useful for Anthropic-compatible providers such as MiniMax.
|
|
595
|
-
|
|
596
|
-
For MiniMax specifically:
|
|
597
|
-
|
|
598
|
-
- Use `baseURL: "https://api.minimax.io/anthropic"`.
|
|
599
|
-
- `MiniMax-M3` can emit visible thinking blocks when you set `thinking: { "type": "adaptive" }`.
|
|
600
|
-
- `MiniMax-M2.7` / `M2.5` / `M2.1` / `M2` do internal reasoning, but MiniMax’s Anthropic-compatible API does not expose those as `thinking` content blocks, so Hooman has nothing to render in the transcript.
|
|
432
|
+
Provider entries now look like:
|
|
601
433
|
|
|
602
434
|
```json
|
|
603
435
|
{
|
|
604
|
-
"
|
|
605
|
-
"
|
|
606
|
-
"
|
|
607
|
-
"apiKey": "..."
|
|
608
|
-
"baseURL": "https://api.minimax.io/anthropic",
|
|
609
|
-
"thinking": { "type": "adaptive" },
|
|
610
|
-
"temperature": 1
|
|
436
|
+
"name": "MiniMax",
|
|
437
|
+
"provider": "minimax",
|
|
438
|
+
"options": {
|
|
439
|
+
"apiKey": "..."
|
|
611
440
|
}
|
|
612
441
|
}
|
|
613
442
|
```
|
|
614
443
|
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
Uses the Vercel AI SDK Groq provider (`@ai-sdk/groq`) on top of Strands `VercelModel`. Provider-specific settings `apiKey`, `baseURL`, and `headers` are picked up; other values are forwarded into the model config (`temperature`, `maxTokens`, etc.). Defaults to `GROQ_API_KEY` from the environment when no `apiKey` is supplied.
|
|
444
|
+
LLM entries reference a provider by name and carry normalized model options:
|
|
618
445
|
|
|
619
446
|
```json
|
|
620
447
|
{
|
|
621
|
-
"
|
|
622
|
-
"
|
|
623
|
-
"
|
|
624
|
-
"
|
|
625
|
-
"temperature":
|
|
626
|
-
|
|
448
|
+
"name": "MiniMax M3",
|
|
449
|
+
"provider": "MiniMax",
|
|
450
|
+
"options": {
|
|
451
|
+
"model": "MiniMax-M3",
|
|
452
|
+
"temperature": 1,
|
|
453
|
+
"maxTokens": 4096
|
|
454
|
+
},
|
|
455
|
+
"default": true
|
|
627
456
|
}
|
|
628
457
|
```
|
|
629
458
|
|
|
630
|
-
|
|
459
|
+
Supported provider option fields:
|
|
631
460
|
|
|
632
|
-
|
|
461
|
+
- `anthropic`: `apiKey`, optional `baseURL`, optional `headers`, optional `thinking`
|
|
462
|
+
- `azure`: optional `resourceName`, optional `baseURL`, optional `apiKey`, optional `headers`, optional `apiVersion`, optional `useDeploymentBasedUrls`
|
|
463
|
+
- `bedrock`: `region`, `accessKeyId`, `secretAccessKey`, optional `sessionToken`, optional `apiKey`
|
|
464
|
+
- `google`: `apiKey`
|
|
465
|
+
- `groq`: `apiKey`, optional `baseURL`, optional `headers`
|
|
466
|
+
- `minimax`: `apiKey`, optional `headers`, optional `thinking`
|
|
467
|
+
- `moonshot`: `apiKey`, optional `baseURL`, optional `headers`
|
|
468
|
+
- `ollama`: optional `baseURL`, optional `thinking`
|
|
469
|
+
- `openai`: `apiKey`, optional `baseURL`, optional `headers`
|
|
470
|
+
- `openrouter`: `apiKey`, optional `baseURL`, optional `headers`
|
|
471
|
+
- `xai`: `apiKey`, optional `baseURL`, optional `headers`
|
|
633
472
|
|
|
634
|
-
|
|
635
|
-
{
|
|
636
|
-
"provider": "moonshot",
|
|
637
|
-
"model": "kimi-k2.5",
|
|
638
|
-
"params": {
|
|
639
|
-
"apiKey": "...",
|
|
640
|
-
"temperature": 0.7
|
|
641
|
-
}
|
|
642
|
-
}
|
|
643
|
-
```
|
|
473
|
+
Normalized LLM option fields:
|
|
644
474
|
|
|
645
|
-
|
|
475
|
+
- `model`
|
|
476
|
+
- optional `temperature`
|
|
477
|
+
- optional `maxTokens`
|
|
646
478
|
|
|
647
|
-
|
|
479
|
+
Notes:
|
|
648
480
|
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
}
|
|
657
|
-
}
|
|
658
|
-
```
|
|
481
|
+
- Google maps normalized `maxTokens` to the SDK's `maxOutputTokens` internally.
|
|
482
|
+
- Azure uses the Vercel AI SDK `@ai-sdk/azure` provider. Set the LLM `model` to your Azure deployment name, not the raw OpenAI model id.
|
|
483
|
+
- Ollama maps normalized `temperature` into Ollama `options.temperature`.
|
|
484
|
+
- MiniMax uses the Anthropic-compatible endpoint `https://api.minimax.io/anthropic` automatically.
|
|
485
|
+
- Moonshot defaults `baseURL` to `https://api.moonshot.ai/v1` when it is omitted.
|
|
486
|
+
- OpenRouter defaults `baseURL` to `https://openrouter.ai/api/v1` when it is omitted, and model names are usually provider-qualified ids such as `anthropic/claude-3.5-sonnet`.
|
|
487
|
+
- Bedrock can rely on the AWS default credential chain when explicit credentials are not provided.
|
|
659
488
|
|
|
660
489
|
## MCP Configuration
|
|
661
490
|
|
|
@@ -669,6 +498,8 @@ Detailed design notes for planned OAuth-enabled remote MCP support live in [docs
|
|
|
669
498
|
}
|
|
670
499
|
```
|
|
671
500
|
|
|
501
|
+
At runtime, project-local `mcp.json` files are merged on top of `~/.hooman/mcp.json` from git root to current directory. On name conflicts, the nearest `mcpServers.<name>` entry wins.
|
|
502
|
+
|
|
672
503
|
### Example stdio server
|
|
673
504
|
|
|
674
505
|
```json
|
|
@@ -797,6 +628,19 @@ Run typecheck:
|
|
|
797
628
|
npm run typecheck
|
|
798
629
|
```
|
|
799
630
|
|
|
631
|
+
Build the project:
|
|
632
|
+
|
|
633
|
+
```bash
|
|
634
|
+
npm run build
|
|
635
|
+
```
|
|
636
|
+
|
|
637
|
+
After making any code change, run both verification steps:
|
|
638
|
+
|
|
639
|
+
```bash
|
|
640
|
+
npm run typecheck
|
|
641
|
+
npm run build
|
|
642
|
+
```
|
|
643
|
+
|
|
800
644
|
## License
|
|
801
645
|
|
|
802
646
|
MIT. See `LICENSE`.
|
package/dist/acp/acp-agent.js
CHANGED
|
@@ -17,7 +17,6 @@ import { copyAgentAppState } from "../core/state/agent-app-state.js";
|
|
|
17
17
|
import { getModeState } from "../core/state/session-mode.js";
|
|
18
18
|
import { ENTER_PLAN_MODE_TOOL, EXIT_PLAN_MODE_TOOL, } from "../core/state/tool-approvals.js";
|
|
19
19
|
import { isYoloEnabled } from "../core/state/yolo.js";
|
|
20
|
-
import { extractAcpClientSystemPrompt } from "./meta/system-prompt.js";
|
|
21
20
|
import { extractAcpClientUserId } from "./meta/user-id.js";
|
|
22
21
|
import { deriveSessionTitleFromEcho } from "./sessions/title.js";
|
|
23
22
|
import { acpPromptEchoText, acpPromptToInvokeArgs } from "./prompt-invoke.js";
|
|
@@ -230,7 +229,6 @@ export class AcpAgent {
|
|
|
230
229
|
assertAbsolutePath(params.cwd, "cwd");
|
|
231
230
|
const sessionId = crypto.randomUUID();
|
|
232
231
|
const clientUserId = extractAcpClientUserId(params._meta) ?? null;
|
|
233
|
-
const clientSystemPrompt = extractAcpClientSystemPrompt(params._meta) ?? null;
|
|
234
232
|
const bootstrapUserId = clientUserId ?? sessionId;
|
|
235
233
|
const mcpServers = normalizeAcpSessionMcpServers(params.mcpServers);
|
|
236
234
|
const now = new Date().toISOString();
|
|
@@ -240,7 +238,6 @@ export class AcpAgent {
|
|
|
240
238
|
updatedAt: now,
|
|
241
239
|
title: null,
|
|
242
240
|
userId: clientUserId,
|
|
243
|
-
systemPrompt: clientSystemPrompt,
|
|
244
241
|
mcpServers,
|
|
245
242
|
};
|
|
246
243
|
await writeSessionMeta(this.#acpRoot, sessionId, meta);
|
|
@@ -253,7 +250,6 @@ export class AcpAgent {
|
|
|
253
250
|
],
|
|
254
251
|
acp: {
|
|
255
252
|
mcpServers,
|
|
256
|
-
...(clientSystemPrompt ? { systemPrompt: clientSystemPrompt } : {}),
|
|
257
253
|
},
|
|
258
254
|
}, false, createSessionConfig());
|
|
259
255
|
const config = bootConfig;
|
|
@@ -308,13 +304,8 @@ export class AcpAgent {
|
|
|
308
304
|
}
|
|
309
305
|
assertAbsolutePath(params.cwd, "cwd");
|
|
310
306
|
const fromRequest = extractAcpClientUserId(params._meta);
|
|
311
|
-
const requestedSystemPrompt = extractAcpClientSystemPrompt(params._meta);
|
|
312
307
|
const storedUserId = existing.userId ?? null;
|
|
313
|
-
const storedSystemPrompt = existing.systemPrompt ?? null;
|
|
314
308
|
const clientUserId = fromRequest !== undefined ? fromRequest : storedUserId;
|
|
315
|
-
const clientSystemPrompt = requestedSystemPrompt !== undefined
|
|
316
|
-
? requestedSystemPrompt
|
|
317
|
-
: storedSystemPrompt;
|
|
318
309
|
const bootstrapUserId = clientUserId ?? params.sessionId;
|
|
319
310
|
const mcpServers = params.mcpServers.length > 0
|
|
320
311
|
? normalizeAcpSessionMcpServers(params.mcpServers)
|
|
@@ -323,14 +314,13 @@ export class AcpAgent {
|
|
|
323
314
|
userId: bootstrapUserId,
|
|
324
315
|
sessionId: params.sessionId,
|
|
325
316
|
yolo: existing.yolo === true,
|
|
326
|
-
|
|
317
|
+
mode: existing.sessionMode ?? "agent",
|
|
327
318
|
createInterventions: () => [
|
|
328
319
|
createAcpToolApprovalIntervention(this.#connection, params.sessionId, () => this.#sessions.get(params.sessionId)?.streamedToolCallIds ??
|
|
329
320
|
EMPTY_STREAMED_TOOL_CALL_IDS),
|
|
330
321
|
],
|
|
331
322
|
acp: {
|
|
332
323
|
mcpServers,
|
|
333
|
-
...(clientSystemPrompt ? { systemPrompt: clientSystemPrompt } : {}),
|
|
334
324
|
},
|
|
335
325
|
}, false, createSessionConfig());
|
|
336
326
|
const config = bootConfig;
|
|
@@ -366,9 +356,6 @@ export class AcpAgent {
|
|
|
366
356
|
cwd: params.cwd,
|
|
367
357
|
updatedAt: new Date().toISOString(),
|
|
368
358
|
...(fromRequest !== undefined ? { userId: fromRequest || null } : {}),
|
|
369
|
-
...(requestedSystemPrompt !== undefined
|
|
370
|
-
? { systemPrompt: requestedSystemPrompt || null }
|
|
371
|
-
: {}),
|
|
372
359
|
mcpServers,
|
|
373
360
|
});
|
|
374
361
|
return {
|
|
@@ -415,14 +402,13 @@ export class AcpAgent {
|
|
|
415
402
|
userId: bootstrapUserId,
|
|
416
403
|
sessionId,
|
|
417
404
|
yolo: isYoloEnabled(rec.agent),
|
|
418
|
-
|
|
405
|
+
mode: getModeState(rec.agent).mode,
|
|
419
406
|
createInterventions: () => [
|
|
420
407
|
createAcpToolApprovalIntervention(this.#connection, sessionId, () => this.#sessions.get(sessionId)?.streamedToolCallIds ??
|
|
421
408
|
EMPTY_STREAMED_TOOL_CALL_IDS),
|
|
422
409
|
],
|
|
423
410
|
acp: {
|
|
424
411
|
mcpServers,
|
|
425
|
-
...(meta.systemPrompt ? { systemPrompt: meta.systemPrompt } : {}),
|
|
426
412
|
},
|
|
427
413
|
}, false, rec.config);
|
|
428
414
|
const config = bootConfig;
|