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 +38 -37
- package/package.json +1 -1
- package/src/acp/acp-agent.ts +3 -10
- package/src/acp/sessions/config-options.ts +44 -7
- package/src/acp/utils/tool-kind.ts +6 -0
- package/src/acp/utils/tool-locations.ts +2 -0
- package/src/cli.ts +7 -33
- package/src/configure/app.tsx +244 -55
- package/src/configure/types.ts +2 -0
- package/src/configure/utils.ts +21 -0
- package/src/core/agent/index.ts +10 -17
- package/src/core/config.ts +140 -27
- package/src/core/index.ts +1 -9
- package/src/core/prompts/index.ts +2 -7
- package/src/core/prompts/static/ltm.md +39 -28
- package/src/core/prompts/static/wiki.md +81 -0
- package/src/core/prompts/system.ts +12 -11
- package/src/core/tools/index.ts +1 -0
- package/src/core/tools/wiki.ts +703 -0
- package/src/core/prompts/static/memory.md +0 -39
- package/src/core/toolkit.ts +0 -13
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
|
-
###
|
|
158
|
+
### Feature Flags
|
|
159
|
+
|
|
160
|
+
Runtime tools and prompt sections are controlled from `config.json` under `features`:
|
|
177
161
|
|
|
178
|
-
|
|
162
|
+
- `features.fetch.enabled`
|
|
163
|
+
- `features.filesystem.enabled`
|
|
164
|
+
- `features.shell.enabled`
|
|
165
|
+
- `features.ltm.enabled`
|
|
166
|
+
- `features.wiki.enabled`
|
|
179
167
|
|
|
180
|
-
|
|
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
|
-
|
|
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,
|
|
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
|
-
"
|
|
256
|
-
"
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
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
package/src/acp/acp-agent.ts
CHANGED
|
@@ -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
|
|
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(
|
|
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
|
|
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 (
|
|
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
|
-
|
|
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
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
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
|
|
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;
|
|
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
|
-
.
|
|
202
|
-
|
|
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) {
|