@unblocklabs/unblock-memory 0.3.5 → 0.3.7

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.
@@ -123,6 +123,7 @@ function codexPrompt(input) {
123
123
  "Return only the JSON object required by the supplied output schema.",
124
124
  "Preserve useful current claims when evidence still supports them.",
125
125
  "Every claim must cite an evidence source and locator already present in the input.",
126
+ "Copy observedAt from the matching supplied evidence and provide confidence for every claim.",
126
127
  JSON.stringify(input),
127
128
  ].join("\n\n");
128
129
  }
@@ -209,6 +210,20 @@ const CODEX_ENV_KEYS = [
209
210
  function codexEnvironment(source) {
210
211
  return Object.fromEntries(CODEX_ENV_KEYS.flatMap((key) => (source[key] === undefined ? [] : [[key, source[key]]])));
211
212
  }
213
+ function isRecord(value) {
214
+ return value !== null && typeof value === "object" && !Array.isArray(value);
215
+ }
216
+ function codexOutputSchema(value) {
217
+ if (Array.isArray(value))
218
+ return value.map(codexOutputSchema);
219
+ if (!isRecord(value))
220
+ return value;
221
+ const schema = Object.fromEntries(Object.entries(value).map(([key, child]) => [key, codexOutputSchema(child)]));
222
+ if (schema.type === "object" && isRecord(schema.properties)) {
223
+ schema.required = Object.keys(schema.properties);
224
+ }
225
+ return schema;
226
+ }
212
227
  export function createCodexPeopleRefinementRunner(runCommand = runCodexProcess, options = {}) {
213
228
  return async ({ input, outputSchema, signal }) => {
214
229
  const scratch = await mkdtemp(join(tmpdir(), "unblock-memory-people-refinement-"));
@@ -217,7 +232,7 @@ export function createCodexPeopleRefinementRunner(runCommand = runCodexProcess,
217
232
  try {
218
233
  const timeout = AbortSignal.timeout(options.timeoutMs ?? 15 * 60_000);
219
234
  const commandSignal = signal ? AbortSignal.any([signal, timeout]) : timeout;
220
- await writeFile(schemaPath, JSON.stringify(outputSchema), { mode: 0o600 });
235
+ await writeFile(schemaPath, JSON.stringify(codexOutputSchema(outputSchema)), { mode: 0o600 });
221
236
  await runCommand({
222
237
  executable: "codex",
223
238
  args: [
@@ -4,22 +4,41 @@ import { Value } from "typebox/value";
4
4
  import { renderPeopleWhisper } from "./people-hooks.js";
5
5
  import { createOpenClawSlackDirectory, syncSlackDirectory, } from "./slack-directory.js";
6
6
  const nonEmpty = Type.String({ pattern: "\\S", maxLength: 1000 });
7
- const personSelector = Type.Union([
8
- Type.Object({ view: Type.Literal("person"), personId: nonEmpty }, { additionalProperties: false }),
7
+ const inspectParameters = Type.Union([
8
+ Type.Object({
9
+ view: Type.Literal("person"),
10
+ personId: Type.String({
11
+ pattern: "\\S",
12
+ maxLength: 1000,
13
+ description: "PeopleSQL person ID. Use identity when only Slack IDs are known.",
14
+ }),
15
+ }, { additionalProperties: false }),
9
16
  Type.Object({
10
17
  view: Type.Literal("person"),
11
18
  identity: Type.Object({
12
19
  provider: Type.Literal("slack"),
13
- accountScope: nonEmpty,
14
- externalId: nonEmpty,
15
- }, { additionalProperties: false }),
20
+ accountScope: Type.String({
21
+ pattern: "\\S",
22
+ maxLength: 1000,
23
+ description: "Configured Slack account ID, for example default.",
24
+ }),
25
+ externalId: Type.String({
26
+ pattern: "\\S",
27
+ maxLength: 1000,
28
+ description: "Exact Slack user ID.",
29
+ }),
30
+ }, {
31
+ additionalProperties: false,
32
+ description: "Exact Slack identity for the person to inspect.",
33
+ }),
16
34
  }, { additionalProperties: false }),
17
- ]);
18
- const inspectParameters = Type.Union([
19
- personSelector,
20
35
  Type.Object({
21
36
  view: Type.Literal("todos"),
22
- limit: Type.Optional(Type.Integer({ minimum: 1, maximum: 100 })),
37
+ limit: Type.Optional(Type.Integer({
38
+ minimum: 1,
39
+ maximum: 100,
40
+ description: "Maximum actionable todos to return.",
41
+ })),
23
42
  }, { additionalProperties: false }),
24
43
  ]);
25
44
  const updateParameters = Type.Union([
@@ -85,7 +104,7 @@ function createInspectTool(stores, config, ctx) {
85
104
  return {
86
105
  name: "memory_people_inspect",
87
106
  label: "Inspect People Memory",
88
- description: "Inspect one exact person or bounded actionable people todos.",
107
+ description: "Inspect one person by PeopleSQL personId or exact Slack identity, or list bounded actionable people todos.",
89
108
  parameters: inspectParameters,
90
109
  async execute(_toolCallId, raw) {
91
110
  const input = Value.Parse(inspectParameters, raw);
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "id": "unblock-memory",
3
3
  "name": "Unblock Memory",
4
- "version": "0.3.5",
4
+ "version": "0.3.7",
5
5
  "description": "Indexes, retrieves, and analyzes configured workspace memory with existing QMD vectors.",
6
6
  "kind": "memory",
7
7
  "activation": { "onStartup": false },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@unblocklabs/unblock-memory",
3
- "version": "0.3.5",
3
+ "version": "0.3.7",
4
4
  "description": "Workspace-native memory for OpenClaw, powered by QMD",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -41,6 +41,7 @@
41
41
  "typebox": "1.3.6"
42
42
  },
43
43
  "devDependencies": {
44
+ "@openclaw/ai": "2026.8.1-beta.3",
44
45
  "@openclaw/plugin-inspector": "^0.3.10",
45
46
  "@types/node": "^24.6.0",
46
47
  "@types/picomatch": "^4.0.2",