hoomanjs 1.9.0 → 1.11.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 CHANGED
@@ -103,12 +103,6 @@ Use a specific session id:
103
103
  hooman exec "What changed?" --session my-session
104
104
  ```
105
105
 
106
- Choose a toolkit size:
107
-
108
- ```bash
109
- hooman exec "Summarize this repo" --toolkit lite
110
- ```
111
-
112
106
  Skip interactive tool approval (allows every tool call; use only when you trust the prompt and environment):
113
107
 
114
108
  ```bash
@@ -135,12 +129,6 @@ Resume or pin a session id:
135
129
  hooman chat --session my-session
136
130
  ```
137
131
 
138
- Choose a toolkit size:
139
-
140
- ```bash
141
- hooman chat --toolkit max
142
- ```
143
-
144
132
  Skip the in-chat tool approval UI (same semantics as `exec --yolo`):
145
133
 
146
134
  ```bash
@@ -161,27 +149,26 @@ Resume or pin a session id:
161
149
  hooman daemon --session my-daemon --channels
162
150
  ```
163
151
 
164
- Choose a toolkit size:
165
-
166
- ```bash
167
- hooman daemon --toolkit full --channels
168
- ```
169
-
170
152
  Skip remote channel permission relay and allow every tool call from daemon turns (same risk profile as `exec` / `chat` with `--yolo`):
171
153
 
172
154
  ```bash
173
155
  hooman daemon --channels --yolo
174
156
  ```
175
157
 
176
- ### Toolkit Levels
158
+ ### Feature Flags
159
+
160
+ Runtime tools and prompt sections are controlled from `config.json` under `features`:
177
161
 
178
- `exec`, `chat`, `daemon`, and `acp` support `-t, --toolkit <lite|full|max>`.
162
+ - `features.fetch.enabled`
163
+ - `features.filesystem.enabled`
164
+ - `features.shell.enabled`
165
+ - `features.ltm.enabled`
166
+ - `features.wiki.enabled`
179
167
 
180
- - `lite` - time, fetch, long-term-memory, installed skills, and configured MCP server tools
181
- - `full` - `lite` plus filesystem, shell, and thinking tools
182
- - `max` - `full` plus skills management tools and MCP config management tools
168
+ Both `ltm` and `wiki` include dedicated Chroma settings under:
183
169
 
184
- Prompt loading follows the same split: filesystem / shell / thinking instructions are only included from `full` upward, while skills guidance is always included.
170
+ - `features.ltm.chroma` (default collection: `memory`)
171
+ - `features.wiki.chroma` (default collection: `wiki`)
185
172
 
186
173
  ### `hooman configure`
187
174
 
@@ -206,12 +193,6 @@ Run Hooman as an Agent Client Protocol (ACP) agent over stdio.
206
193
  hooman acp
207
194
  ```
208
195
 
209
- Choose a toolkit size for ACP-created sessions:
210
-
211
- ```bash
212
- hooman acp --toolkit max
213
- ```
214
-
215
196
  ACP notes:
216
197
 
217
198
  - ACP sessions are stored under the active Hooman data directory in `acp-sessions/`
@@ -230,7 +211,7 @@ Hooman stores its data in:
230
211
 
231
212
  Important files and folders:
232
213
 
233
- - `config.json` - app name, LLM provider/model, tool approvals, long-term memory, compaction
214
+ - `config.json` - app name, LLM provider/model, tool approvals, feature flags, LTM/wiki settings, compaction
234
215
  - `instructions.md` - system instructions used to build the agent prompt
235
216
  - `mcp.json` - MCP server definitions
236
217
  - `skills/` - installed skills
@@ -252,12 +233,32 @@ This is the shape managed by `hooman configure`:
252
233
  "tools": {
253
234
  "allowed": []
254
235
  },
255
- "ltm": {
256
- "enabled": false,
257
- "chroma": {
258
- "url": "http://127.0.0.1:8000",
259
- "collection": {
260
- "memory": "memory"
236
+ "features": {
237
+ "fetch": {
238
+ "enabled": true
239
+ },
240
+ "filesystem": {
241
+ "enabled": true
242
+ },
243
+ "shell": {
244
+ "enabled": true
245
+ },
246
+ "ltm": {
247
+ "enabled": false,
248
+ "chroma": {
249
+ "url": "http://127.0.0.1:8000",
250
+ "collection": {
251
+ "memory": "memory"
252
+ }
253
+ }
254
+ },
255
+ "wiki": {
256
+ "enabled": false,
257
+ "chroma": {
258
+ "url": "http://127.0.0.1:8000",
259
+ "collection": {
260
+ "wiki": "wiki"
261
+ }
261
262
  }
262
263
  }
263
264
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hoomanjs",
3
- "version": "1.9.0",
3
+ "version": "1.11.0",
4
4
  "description": "Bun-powered local AI agent CLI with chat, exec, ACP, MCP, and skills support.",
5
5
  "author": {
6
6
  "name": "Vaibhav Pandey",
@@ -16,8 +16,6 @@ import {
16
16
  } from "@agentclientprotocol/sdk";
17
17
  import type { Agent as StrandsAgent } from "@strands-agents/sdk";
18
18
  import {
19
- AfterToolCallEvent,
20
- AgentResultEvent,
21
19
  BeforeToolCallEvent,
22
20
  isModelStreamEvent,
23
21
  Message,
@@ -27,7 +25,6 @@ import {
27
25
  import type { StopReason as StrandsStopReason } from "@strands-agents/sdk";
28
26
  import { bootstrap } from "../core/index.ts";
29
27
  import { runWithCwd } from "../core/utils/cwd-context.ts";
30
- import type { Toolkit } from "../core/toolkit.ts";
31
28
  import { acpSessionsRootPath } from "./utils/paths.ts";
32
29
  import { inferToolKind } from "./utils/tool-kind.ts";
33
30
  import { toolResultToAcpContent } from "./utils/tool-result-content.ts";
@@ -172,13 +169,11 @@ export class AcpAgent implements AgentContract {
172
169
  readonly #connection: AgentSideConnection;
173
170
  readonly #sessions = new Map<string, SessionRecord>();
174
171
  readonly #acpRoot: string;
175
- readonly #toolkit: Toolkit;
176
172
  #version: string | null = null;
177
173
 
178
- constructor(connection: AgentSideConnection, toolkit: Toolkit) {
174
+ constructor(connection: AgentSideConnection) {
179
175
  this.#connection = connection;
180
176
  this.#acpRoot = acpSessionsRootPath();
181
- this.#toolkit = toolkit;
182
177
  queueMicrotask(() => {
183
178
  if (connection.signal.aborted) {
184
179
  void this.#disposeAllSessions();
@@ -342,7 +337,6 @@ export class AcpAgent implements AgentContract {
342
337
  {
343
338
  userId: bootstrapUserId,
344
339
  sessionId,
345
- toolkit: this.#toolkit,
346
340
  mcpServers,
347
341
  ...(clientSystemPrompt ? { systemPrompt: clientSystemPrompt } : {}),
348
342
  },
@@ -440,7 +434,6 @@ export class AcpAgent implements AgentContract {
440
434
  {
441
435
  userId: bootstrapUserId,
442
436
  sessionId: params.sessionId,
443
- toolkit: this.#toolkit,
444
437
  mcpServers,
445
438
  ...(clientSystemPrompt ? { systemPrompt: clientSystemPrompt } : {}),
446
439
  },
@@ -804,13 +797,13 @@ export class AcpAgent implements AgentContract {
804
797
  }
805
798
  }
806
799
 
807
- export async function runAcpStdio(toolkit: Toolkit = "full"): Promise<void> {
800
+ export async function runAcpStdio(): Promise<void> {
808
801
  const stream = ndJsonStream(
809
802
  Writable.toWeb(stdout) as unknown as WritableStream<Uint8Array>,
810
803
  Readable.toWeb(stdin) as unknown as ReadableStream<Uint8Array>,
811
804
  );
812
805
  const connection = new AgentSideConnection(
813
- (conn) => new AcpAgent(conn, toolkit),
806
+ (conn) => new AcpAgent(conn),
814
807
  stream,
815
808
  );
816
809
  await connection.closed;
@@ -6,6 +6,7 @@ import type {
6
6
  import type { Config } from "../../core/config.ts";
7
7
 
8
8
  export const HOOMAN_LTM_CONFIG_ID = "hooman.longTermMemory" as const;
9
+ export const HOOMAN_WIKI_CONFIG_ID = "hooman.wiki" as const;
9
10
 
10
11
  export function buildSessionConfigOptions(
11
12
  config: Config,
@@ -24,6 +25,19 @@ export function buildSessionConfigOptions(
24
25
  { value: "off", name: "Off" },
25
26
  ],
26
27
  },
28
+ {
29
+ type: "select",
30
+ id: HOOMAN_WIKI_CONFIG_ID,
31
+ name: "Wiki",
32
+ description:
33
+ "When enabled, the agent can read, write, and search wiki pages (requires Chroma at the configured URL).",
34
+ category: "_hooman",
35
+ currentValue: config.wiki.enabled ? "on" : "off",
36
+ options: [
37
+ { value: "on", name: "On" },
38
+ { value: "off", name: "Off" },
39
+ ],
40
+ },
27
41
  ];
28
42
  }
29
43
 
@@ -36,20 +50,43 @@ export function applySessionConfigOption(
36
50
  message: "Boolean session config options are not supported.",
37
51
  });
38
52
  }
39
- if (params.configId !== HOOMAN_LTM_CONFIG_ID) {
53
+ if (
54
+ params.configId !== HOOMAN_LTM_CONFIG_ID &&
55
+ params.configId !== HOOMAN_WIKI_CONFIG_ID
56
+ ) {
40
57
  throw RequestError.invalidParams({ configId: params.configId });
41
58
  }
42
59
  const value = params.value;
43
60
  if (value !== "on" && value !== "off") {
44
61
  throw RequestError.invalidParams({ value });
45
62
  }
46
- const chroma = config.ltm.chroma;
63
+ if (params.configId === HOOMAN_LTM_CONFIG_ID) {
64
+ const chroma = config.ltm.chroma;
65
+ config.update({
66
+ features: {
67
+ ...config.features,
68
+ ltm: {
69
+ enabled: value === "on",
70
+ chroma: {
71
+ url: chroma.url,
72
+ collection: { memory: chroma.collection.memory },
73
+ },
74
+ },
75
+ },
76
+ });
77
+ return;
78
+ }
79
+
80
+ const chroma = config.wiki.chroma;
47
81
  config.update({
48
- ltm: {
49
- enabled: value === "on",
50
- chroma: {
51
- url: chroma.url,
52
- collection: { memory: chroma.collection.memory },
82
+ features: {
83
+ ...config.features,
84
+ wiki: {
85
+ enabled: value === "on",
86
+ chroma: {
87
+ url: chroma.url,
88
+ collection: { wiki: chroma.collection.wiki },
89
+ },
53
90
  },
54
91
  },
55
92
  });
@@ -15,6 +15,12 @@ const KNOWN_TOOL_KINDS = new Map<string, ToolKind>([
15
15
  ["get_file_info", "read"],
16
16
  ["shell", "execute"],
17
17
  ["fetch", "fetch"],
18
+ ["wiki_list_files", "read"],
19
+ ["wiki_read_file", "read"],
20
+ ["wiki_write_file", "edit"],
21
+ ["wiki_knowledge_graph", "read"],
22
+ ["wiki_stats", "read"],
23
+ ["wiki_search", "search"],
18
24
  ["think", "think"],
19
25
  ["get_current_time", "other"],
20
26
  ["convert_time", "other"],
@@ -11,6 +11,8 @@ const KNOWN_TOOL_LOCATION_KEYS = new Map<string, readonly string[]>([
11
11
  ["move_file", ["source", "destination"]],
12
12
  ["search_files", ["path"]],
13
13
  ["get_file_info", ["path"]],
14
+ ["wiki_read_file", ["path"]],
15
+ ["wiki_write_file", ["path"]],
14
16
  ]);
15
17
 
16
18
  /** ACP `locations` extracted only from known core filesystem tools. */
package/src/cli.ts CHANGED
@@ -1,10 +1,8 @@
1
1
  #!/usr/bin/env bun
2
2
 
3
- import { Command, Option } from "commander";
3
+ import { Command } from "commander";
4
4
  import { BeforeToolCallEvent } from "@strands-agents/sdk";
5
5
  import { bootstrap } from "./core/index.ts";
6
- import { TOOLKITS } from "./core/toolkit.ts";
7
- import type { Toolkit } from "./core/toolkit.ts";
8
6
  import { createToolApprovalHandler } from "./exec/approvals.ts";
9
7
  import { chat } from "./chat/index.tsx";
10
8
  import { configure } from "./configure/index.tsx";
@@ -37,15 +35,6 @@ async function readPackageMeta(): Promise<{
37
35
  };
38
36
  }
39
37
 
40
- function createToolkitOption(): Option {
41
- return new Option(
42
- "-t, --toolkit <toolkit>",
43
- "Toolkit size to enable: lite, full, or max.",
44
- )
45
- .choices([...TOOLKITS])
46
- .default("full");
47
- }
48
-
49
38
  const packageMeta = await readPackageMeta();
50
39
 
51
40
  const program = new Command()
@@ -60,21 +49,14 @@ program
60
49
  .argument("<prompt>", "Prompt to run once.")
61
50
  .option("-s, --session <id>", "Session ID to use.")
62
51
  .option("--yolo", "Allow all tools without prompting for approval.")
63
- .addOption(createToolkitOption())
64
52
  .action(
65
- async (
66
- prompt: string,
67
- options: { session?: string; toolkit?: Toolkit; yolo?: boolean },
68
- ) => {
53
+ async (prompt: string, options: { session?: string; yolo?: boolean }) => {
69
54
  const sessionId = options.session?.trim() || crypto.randomUUID();
70
55
  const {
71
56
  config,
72
57
  agent,
73
58
  mcp: { manager },
74
- } = await bootstrap(
75
- { sessionId, toolkit: options.toolkit ?? "full" },
76
- true,
77
- );
59
+ } = await bootstrap({ sessionId }, true);
78
60
  agent.addHook(
79
61
  BeforeToolCallEvent,
80
62
  createToolApprovalHandler(config, { yolo: Boolean(options.yolo) }),
@@ -95,11 +77,10 @@ program
95
77
  .argument("[prompt]", "Optional initial prompt to run after startup.")
96
78
  .option("-s, --session <id>", "Session ID to use.")
97
79
  .option("--yolo", "Allow all tools without prompting for approval.")
98
- .addOption(createToolkitOption())
99
80
  .action(
100
81
  async (
101
82
  prompt: string | undefined,
102
- options: { session?: string; toolkit?: Toolkit; yolo?: boolean },
83
+ options: { session?: string; yolo?: boolean },
103
84
  ) => {
104
85
  const sessionId = options.session?.trim() || crypto.randomUUID();
105
86
  const {
@@ -107,10 +88,7 @@ program
107
88
  agent,
108
89
  mcp: { manager },
109
90
  registry,
110
- } = await bootstrap(
111
- { sessionId, toolkit: options.toolkit ?? "full" },
112
- false,
113
- );
91
+ } = await bootstrap({ sessionId }, false);
114
92
 
115
93
  try {
116
94
  await chat({
@@ -142,11 +120,9 @@ program
142
120
  "Log each MCP channel notification payload to the console.",
143
121
  )
144
122
  .option("--yolo", "Allow all tools without remote approval or prompts.")
145
- .addOption(createToolkitOption())
146
123
  .action(
147
124
  async (options: {
148
125
  session?: string;
149
- toolkit?: Toolkit;
150
126
  channels?: boolean;
151
127
  debug?: boolean;
152
128
  yolo?: boolean;
@@ -160,7 +136,6 @@ program
160
136
  {
161
137
  sessionId: session,
162
138
  userId: session,
163
- toolkit: options.toolkit ?? "full",
164
139
  },
165
140
  true,
166
141
  );
@@ -198,9 +173,8 @@ program
198
173
  .description(
199
174
  "Run as an Agent Client Protocol (ACP) agent on stdio for ACP-compatible clients.",
200
175
  )
201
- .addOption(createToolkitOption())
202
- .action(async (options: { toolkit?: Toolkit }) => {
203
- await runAcpStdio(options.toolkit ?? "full");
176
+ .action(async () => {
177
+ await runAcpStdio();
204
178
  });
205
179
 
206
180
  if (process.argv.slice(2).length === 0) {