@hyperspell/openclaw-hyperspell 0.10.0 → 0.11.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/client.ts +29 -3
- package/commands/slash.ts +84 -13
- package/config.test.ts +202 -0
- package/config.ts +163 -0
- package/hooks/auto-context.ts +44 -7
- package/hooks/auto-trace.test.ts +81 -0
- package/hooks/auto-trace.ts +69 -9
- package/hooks/emotional-state.test.ts +160 -0
- package/hooks/emotional-state.ts +93 -11
- package/index.ts +13 -2
- package/lib/sender.test.ts +234 -0
- package/lib/sender.ts +178 -20
- package/lib/voice-id.ts +39 -0
- package/openclaw.plugin.json +37 -0
- package/package.json +3 -2
- package/tools/remember.ts +69 -5
- package/tools/search.ts +34 -5
package/tools/search.ts
CHANGED
|
@@ -1,13 +1,19 @@
|
|
|
1
1
|
import { Type } from "@sinclair/typebox"
|
|
2
2
|
import type { HyperspellClient } from "../client.ts"
|
|
3
|
-
import type { HyperspellConfig } from "../config.ts"
|
|
4
|
-
import { resolveUser } from "../lib/sender.ts"
|
|
3
|
+
import type { CanReadScope, HyperspellConfig } from "../config.ts"
|
|
4
|
+
import { buildScopeFilter, getCanReadScopes, resolveUser } from "../lib/sender.ts"
|
|
5
5
|
import { log } from "../logger.ts"
|
|
6
6
|
|
|
7
7
|
export function createSearchToolFactory(
|
|
8
8
|
client: HyperspellClient,
|
|
9
9
|
cfg: HyperspellConfig,
|
|
10
10
|
) {
|
|
11
|
+
const scopingEnabled = !!cfg.multiUser?.scoping
|
|
12
|
+
const availableScopes = cfg.multiUser?.scoping?.scopes ?? []
|
|
13
|
+
const scopeDescription = scopingEnabled
|
|
14
|
+
? `Narrow search to a single privacy scope. Available: ${availableScopes.join(", ")}. Omit to search all scopes visible to the caller's role.`
|
|
15
|
+
: "Privacy scope (only used when scoping is enabled in config)."
|
|
16
|
+
|
|
11
17
|
return (ctx: Record<string, unknown>) => ({
|
|
12
18
|
name: "hyperspell_search",
|
|
13
19
|
label: "Memory Search",
|
|
@@ -30,17 +36,39 @@ export function createSearchToolFactory(
|
|
|
30
36
|
"Search as a specific user (e.g. 'ben', 'shared'). Omit to search as current sender.",
|
|
31
37
|
}),
|
|
32
38
|
),
|
|
39
|
+
scope: Type.Optional(Type.String({ description: scopeDescription })),
|
|
33
40
|
}),
|
|
34
41
|
async execute(
|
|
35
42
|
_toolCallId: string,
|
|
36
|
-
params: {
|
|
43
|
+
params: {
|
|
44
|
+
query: string
|
|
45
|
+
limit?: number
|
|
46
|
+
after?: string
|
|
47
|
+
before?: string
|
|
48
|
+
userId?: string
|
|
49
|
+
scope?: string
|
|
50
|
+
},
|
|
37
51
|
) {
|
|
38
52
|
const limit = params.limit ?? 5
|
|
39
|
-
// Resolve userId: explicit param > sender resolution > config default
|
|
40
53
|
const resolved = resolveUser(ctx, cfg)
|
|
41
54
|
const userId = params.userId ?? resolved?.userId
|
|
55
|
+
|
|
56
|
+
// Build scope filter: intersect requested scope (if any) with caller's canRead
|
|
57
|
+
let filter: Record<string, unknown> | undefined
|
|
58
|
+
if (scopingEnabled) {
|
|
59
|
+
const canRead = getCanReadScopes(resolved, cfg)
|
|
60
|
+
const allowed: CanReadScope[] = params.scope
|
|
61
|
+
? canRead.includes("*")
|
|
62
|
+
? [params.scope]
|
|
63
|
+
: canRead.includes(params.scope)
|
|
64
|
+
? [params.scope]
|
|
65
|
+
: [] // requested scope not allowed → match nothing
|
|
66
|
+
: canRead
|
|
67
|
+
filter = buildScopeFilter(allowed, resolved?.userId ?? "")
|
|
68
|
+
}
|
|
69
|
+
|
|
42
70
|
log.debug(
|
|
43
|
-
`search tool: query="${params.query}" limit=${limit} after=${params.after ?? "none"} before=${params.before ?? "none"} userId=${userId}`,
|
|
71
|
+
`search tool: query="${params.query}" limit=${limit} after=${params.after ?? "none"} before=${params.before ?? "none"} userId=${userId} scope=${params.scope ?? "any"}`,
|
|
44
72
|
)
|
|
45
73
|
|
|
46
74
|
try {
|
|
@@ -49,6 +77,7 @@ export function createSearchToolFactory(
|
|
|
49
77
|
after: params.after,
|
|
50
78
|
before: params.before,
|
|
51
79
|
userId,
|
|
80
|
+
filter,
|
|
52
81
|
})
|
|
53
82
|
const documents = (response.documents ?? []) as Array<{
|
|
54
83
|
source: string
|