hoomanjs 1.17.0 → 1.17.1
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/package.json
CHANGED
package/src/core/agent/index.ts
CHANGED
|
@@ -53,15 +53,9 @@ export async function create(
|
|
|
53
53
|
const ltm = config.tools.ltm.enabled
|
|
54
54
|
? createLongTermMemoryStore(config)
|
|
55
55
|
: null;
|
|
56
|
-
const skills =
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
const prefixed = config.tools.mcp.enabled
|
|
60
|
-
? await mcp.manager.listPrefixedTools()
|
|
61
|
-
: [];
|
|
62
|
-
const append = config.tools.mcp.enabled
|
|
63
|
-
? await mcp.manager.listServerInstructions()
|
|
64
|
-
: [];
|
|
56
|
+
const skills = (await createSkillsPrompt(registry)).content;
|
|
57
|
+
const prefixed = await mcp.manager.listPrefixedTools();
|
|
58
|
+
const append = await mcp.manager.listServerInstructions();
|
|
65
59
|
const prompt = [system.content, meta.systemPrompt, ...append, skills]
|
|
66
60
|
.filter((x) => !!x)
|
|
67
61
|
.join(SECTION_BREAK);
|
package/src/core/mcp/manager.ts
CHANGED
|
@@ -15,16 +15,11 @@ export const HOOMAN_CHANNEL_PERMISSION = "hooman/channel/permission";
|
|
|
15
15
|
const HOOMAN_CHANNEL_PERMISSION_METHOD = `notifications/${HOOMAN_CHANNEL_PERMISSION}`;
|
|
16
16
|
|
|
17
17
|
export type ChannelMessageMeta = {
|
|
18
|
-
|
|
19
|
-
channel: string;
|
|
20
|
-
method: string;
|
|
21
|
-
params: unknown;
|
|
18
|
+
subscription: ChannelSubscription;
|
|
22
19
|
source?: string;
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
thread?: string;
|
|
27
|
-
};
|
|
20
|
+
user?: string;
|
|
21
|
+
session?: string;
|
|
22
|
+
thread?: string;
|
|
28
23
|
};
|
|
29
24
|
|
|
30
25
|
export type ChannelMessage = {
|
|
@@ -325,7 +320,7 @@ export class Manager {
|
|
|
325
320
|
params?: unknown;
|
|
326
321
|
}) => {
|
|
327
322
|
const { method, params } = notification;
|
|
328
|
-
const prompt = this.toChannelPrompt(
|
|
323
|
+
const prompt = this.toChannelPrompt(params);
|
|
329
324
|
if (!prompt) {
|
|
330
325
|
return;
|
|
331
326
|
}
|
|
@@ -335,16 +330,11 @@ export class Manager {
|
|
|
335
330
|
prompt,
|
|
336
331
|
attachments,
|
|
337
332
|
meta: {
|
|
338
|
-
server,
|
|
339
|
-
channel,
|
|
340
|
-
method,
|
|
341
|
-
params,
|
|
333
|
+
subscription: { server, channel },
|
|
342
334
|
source: readSourceValue(params),
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
thread: readPathValue(params, thread),
|
|
347
|
-
},
|
|
335
|
+
user: readPathValue(params, user),
|
|
336
|
+
session: readPathValue(params, session),
|
|
337
|
+
thread: readPathValue(params, thread),
|
|
348
338
|
},
|
|
349
339
|
});
|
|
350
340
|
};
|
|
@@ -463,20 +453,39 @@ export class Manager {
|
|
|
463
453
|
}
|
|
464
454
|
}
|
|
465
455
|
|
|
466
|
-
private toChannelPrompt(
|
|
456
|
+
private toChannelPrompt(params?: unknown): string {
|
|
457
|
+
const parts = [];
|
|
458
|
+
|
|
467
459
|
if (
|
|
468
460
|
params &&
|
|
469
461
|
typeof params === "object" &&
|
|
470
462
|
"content" in params &&
|
|
471
463
|
typeof params.content === "string"
|
|
472
464
|
) {
|
|
473
|
-
|
|
465
|
+
parts.push(params.content.trim());
|
|
474
466
|
}
|
|
475
467
|
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
468
|
+
if (
|
|
469
|
+
params &&
|
|
470
|
+
typeof params === "object" &&
|
|
471
|
+
"attachments" in params &&
|
|
472
|
+
Array.isArray(params.attachments) &&
|
|
473
|
+
params.attachments.length > 0
|
|
474
|
+
) {
|
|
475
|
+
parts.push("User sent attachments.");
|
|
480
476
|
}
|
|
477
|
+
|
|
478
|
+
if (
|
|
479
|
+
params &&
|
|
480
|
+
typeof params === "object" &&
|
|
481
|
+
"event" in params &&
|
|
482
|
+
typeof params.event === "object"
|
|
483
|
+
) {
|
|
484
|
+
parts.push(
|
|
485
|
+
"Raw event data:\n```json\n" + JSON.stringify(params.event) + "\n```",
|
|
486
|
+
);
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
return parts.filter(Boolean).join("\n").trim();
|
|
481
490
|
}
|
|
482
491
|
}
|
|
@@ -12,6 +12,8 @@ type EnvironmentPromptContext = {
|
|
|
12
12
|
osVersion: string;
|
|
13
13
|
shell: string;
|
|
14
14
|
isGitRepo: boolean;
|
|
15
|
+
currentDateTime: string;
|
|
16
|
+
timeZone: string;
|
|
15
17
|
};
|
|
16
18
|
|
|
17
19
|
function detectPlatform(): string {
|
|
@@ -50,13 +52,20 @@ function detectGitRepo(startDir: string): boolean {
|
|
|
50
52
|
}
|
|
51
53
|
}
|
|
52
54
|
|
|
55
|
+
function detectTimeZone(): string {
|
|
56
|
+
return Intl.DateTimeFormat().resolvedOptions().timeZone || "unknown";
|
|
57
|
+
}
|
|
58
|
+
|
|
53
59
|
export function getEnvironmentPromptContext(): EnvironmentPromptContext {
|
|
54
60
|
const cwd = process.cwd();
|
|
61
|
+
const now = new Date();
|
|
55
62
|
return {
|
|
56
63
|
cwd,
|
|
57
64
|
platform: detectPlatform(),
|
|
58
65
|
osVersion: detectOsVersion(),
|
|
59
66
|
shell: detectShell(),
|
|
60
67
|
isGitRepo: detectGitRepo(cwd),
|
|
68
|
+
currentDateTime: now.toString(),
|
|
69
|
+
timeZone: detectTimeZone(),
|
|
61
70
|
};
|
|
62
71
|
}
|
|
@@ -7,9 +7,11 @@ You are running in the following runtime environment:
|
|
|
7
7
|
- Shell: `{{ environment.shell }}`
|
|
8
8
|
- OS version: `{{ environment.osVersion }}`
|
|
9
9
|
- Is git repository: `{{ environment.isGitRepo }}`
|
|
10
|
+
- Current date/time: `{{ environment.currentDateTime }}`
|
|
11
|
+
- Time zone: `{{ environment.timeZone }}`
|
|
10
12
|
|
|
11
13
|
### How To Use This
|
|
12
14
|
|
|
13
15
|
- Use this information to choose correct path handling, shell syntax, and platform-specific behavior
|
|
14
|
-
- Treat this section as runtime context
|
|
15
|
-
- If the task needs
|
|
16
|
+
- Treat this section as runtime context captured when the prompt was built
|
|
17
|
+
- If the task needs precise current time during a later turn, call `get_current_time`
|
package/src/daemon/index.ts
CHANGED
|
@@ -32,23 +32,23 @@ function resolveSessionId(
|
|
|
32
32
|
message: ChannelMessage,
|
|
33
33
|
fallback?: string,
|
|
34
34
|
): string | undefined {
|
|
35
|
-
const raw = message.meta.
|
|
35
|
+
const raw = message.meta.session?.trim() || fallback;
|
|
36
36
|
if (!raw) return undefined;
|
|
37
37
|
// Namespace per `server:channel` so the same chat id coming from two
|
|
38
38
|
// different MCP servers (or two channels on the same server) never collide.
|
|
39
|
-
return `${message.meta.server}:${message.meta.channel}:${raw}`;
|
|
39
|
+
return `${message.meta.subscription.server}:${message.meta.subscription.channel}:${raw}`;
|
|
40
40
|
}
|
|
41
41
|
|
|
42
42
|
function resolveUserId(
|
|
43
43
|
message: ChannelMessage,
|
|
44
44
|
session?: string,
|
|
45
45
|
): string | undefined {
|
|
46
|
-
const raw = message.meta.
|
|
46
|
+
const raw = message.meta.user?.trim();
|
|
47
47
|
if (!raw) return session;
|
|
48
48
|
// Same user id across different servers is not the same human, so scope
|
|
49
49
|
// user ids by server. Channel is intentionally omitted so long-term memory
|
|
50
50
|
// can stay consistent for a user across rooms within one server.
|
|
51
|
-
return `${message.meta.server}:${raw}`;
|
|
51
|
+
return `${message.meta.subscription.server}:${raw}`;
|
|
52
52
|
}
|
|
53
53
|
|
|
54
54
|
function formatSubscriptions(
|
|
@@ -91,7 +91,7 @@ export async function main(options: RunDaemonOptions): Promise<void> {
|
|
|
91
91
|
|
|
92
92
|
const [queue, stop] = await createQueue(
|
|
93
93
|
async (message: ChannelMessage) => {
|
|
94
|
-
const tag = `${message.meta.server}:${message.meta.channel}`;
|
|
94
|
+
const tag = `${message.meta.subscription.server}:${message.meta.subscription.channel}`;
|
|
95
95
|
const session = resolveSessionId(message, options.session);
|
|
96
96
|
const user = resolveUserId(message, session);
|
|
97
97
|
|
|
@@ -103,18 +103,12 @@ export async function main(options: RunDaemonOptions): Promise<void> {
|
|
|
103
103
|
options.agent.appState.set("userId", user);
|
|
104
104
|
options.agent.appState.set("sessionId", session);
|
|
105
105
|
const origin = {
|
|
106
|
-
server: message.meta.server,
|
|
107
|
-
channel: message.meta.channel,
|
|
106
|
+
server: message.meta.subscription.server,
|
|
107
|
+
channel: message.meta.subscription.channel,
|
|
108
108
|
...(message.meta.source ? { source: message.meta.source } : {}),
|
|
109
|
-
...(message.meta.
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
...(message.meta.identity.session
|
|
113
|
-
? { session: message.meta.identity.session }
|
|
114
|
-
: {}),
|
|
115
|
-
...(message.meta.identity.thread
|
|
116
|
-
? { thread: message.meta.identity.thread }
|
|
117
|
-
: {}),
|
|
109
|
+
...(message.meta.user ? { user: message.meta.user } : {}),
|
|
110
|
+
...(message.meta.session ? { session: message.meta.session } : {}),
|
|
111
|
+
...(message.meta.thread ? { thread: message.meta.thread } : {}),
|
|
118
112
|
};
|
|
119
113
|
options.agent.appState.set("origin", {
|
|
120
114
|
...origin,
|
|
@@ -143,7 +137,7 @@ export async function main(options: RunDaemonOptions): Promise<void> {
|
|
|
143
137
|
channels,
|
|
144
138
|
(message) => {
|
|
145
139
|
debug(
|
|
146
|
-
`received notification → ${message.meta.server}:${message.meta.channel}`,
|
|
140
|
+
`received notification → ${message.meta.subscription.server}:${message.meta.subscription.channel}`,
|
|
147
141
|
);
|
|
148
142
|
void queue.push(message);
|
|
149
143
|
},
|