@eleboucher/pi-memini 0.5.12 → 0.6.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/dist/index.d.ts +1 -0
- package/dist/index.js +37 -3
- package/package.json +2 -1
package/dist/index.d.ts
CHANGED
|
@@ -31,6 +31,7 @@ export declare function floatEnv(name: string, def: number): number;
|
|
|
31
31
|
*/
|
|
32
32
|
export declare function labelsEnv(name?: string): Set<string>;
|
|
33
33
|
export declare function sanitizeNamespace(s: string): string;
|
|
34
|
+
export declare function sanitizeNamespacePath(s: string): string;
|
|
34
35
|
export declare function deriveNamespace(cwd: string | undefined): string;
|
|
35
36
|
export interface ResolvedConfig {
|
|
36
37
|
base_url: string;
|
package/dist/index.js
CHANGED
|
@@ -18,6 +18,7 @@
|
|
|
18
18
|
* MEMINI_API_KEY stay in the environment. See ../README.md for the table.
|
|
19
19
|
*/
|
|
20
20
|
import { Type } from "typebox";
|
|
21
|
+
import { resolveNamespace } from "@memini/namespace-resolver";
|
|
21
22
|
const DEFAULT_BASE_URL = "http://localhost:8080";
|
|
22
23
|
const DEFAULT_TIMEOUT_MS = 30000;
|
|
23
24
|
const DEFAULT_RECALL_LIMIT = 3;
|
|
@@ -72,6 +73,17 @@ export function sanitizeNamespace(s) {
|
|
|
72
73
|
.replace(/[^A-Za-z0-9._-]+/g, "-")
|
|
73
74
|
.replace(/^-+|-+$/g, "");
|
|
74
75
|
}
|
|
76
|
+
// sanitizeNamespacePath sanitizes a hierarchical namespace per segment,
|
|
77
|
+
// preserving the "/" separators the resolver's tenant paths carry
|
|
78
|
+
// (work/memini must not flatten to work-memini — the other integrations keep
|
|
79
|
+
// the separator, and flattening would split memory across integrations).
|
|
80
|
+
export function sanitizeNamespacePath(s) {
|
|
81
|
+
return String(s)
|
|
82
|
+
.split("/")
|
|
83
|
+
.map(sanitizeNamespace)
|
|
84
|
+
.filter(Boolean)
|
|
85
|
+
.join("/");
|
|
86
|
+
}
|
|
75
87
|
// deriveNamespace scopes memory to the project: the basename of the working
|
|
76
88
|
// directory, the same scheme memini auto-resolves from a git repo. Returns ""
|
|
77
89
|
// when no path is given.
|
|
@@ -86,14 +98,37 @@ export function deriveNamespace(cwd) {
|
|
|
86
98
|
// testing.
|
|
87
99
|
export function resolveConfig(env, cwd) {
|
|
88
100
|
const e = env || {};
|
|
89
|
-
const
|
|
101
|
+
const nsEnv = (e.MEMINI_NAMESPACE || "").trim();
|
|
102
|
+
let namespace;
|
|
103
|
+
if (nsEnv) {
|
|
104
|
+
// MEMINI_NAMESPACE wins and is used raw-trimmed (the server validates the
|
|
105
|
+
// header). Routing it through sanitizeNamespacePath would alter an explicit
|
|
106
|
+
// value — the canonical resolver returns it untouched.
|
|
107
|
+
namespace = nsEnv;
|
|
108
|
+
}
|
|
109
|
+
else if (cwd) {
|
|
110
|
+
const { namespace: resolvedNs } = resolveNamespace({
|
|
111
|
+
cwd,
|
|
112
|
+
env: e,
|
|
113
|
+
integration: "pi",
|
|
114
|
+
});
|
|
115
|
+
// Per-segment sanitize: resolver output may be a tenant path (work/memini).
|
|
116
|
+
namespace = sanitizeNamespacePath(resolvedNs) || DEFAULT_NAMESPACE;
|
|
117
|
+
}
|
|
118
|
+
else {
|
|
119
|
+
// No explicit namespace and no cwd to resolve against.
|
|
120
|
+
namespace = DEFAULT_NAMESPACE;
|
|
121
|
+
}
|
|
90
122
|
const recall_limit = (() => {
|
|
91
123
|
const n = Number(e.MEMINI_RECALL_LIMIT);
|
|
92
124
|
return Number.isFinite(n) && n >= 0 ? n : DEFAULT_RECALL_LIMIT;
|
|
93
125
|
})();
|
|
94
126
|
return {
|
|
95
127
|
base_url: e.MEMINI_BASE_URL || e.MEMINI_URL || DEFAULT_BASE_URL,
|
|
96
|
-
namespace
|
|
128
|
+
// namespace is already resolved above (raw-trimmed on the env path,
|
|
129
|
+
// per-segment sanitized on the resolver path); re-sanitizing here would
|
|
130
|
+
// flatten tenant separators.
|
|
131
|
+
namespace: namespace || DEFAULT_NAMESPACE,
|
|
97
132
|
recall: envBool(e.MEMINI_RECALL, true),
|
|
98
133
|
capture: envBool(e.MEMINI_CAPTURE, true),
|
|
99
134
|
recall_limit,
|
|
@@ -453,7 +488,6 @@ export default function meminiExtension(pi) {
|
|
|
453
488
|
metadata.session_id = sid;
|
|
454
489
|
const stored = await client.postJson("/v1/memories", {
|
|
455
490
|
content: buildTurnContent(userText, assistantText),
|
|
456
|
-
tier: "episodic",
|
|
457
491
|
tags: ["pi"],
|
|
458
492
|
metadata,
|
|
459
493
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@eleboucher/pi-memini",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.1",
|
|
4
4
|
"description": "Shared cross-session memory for the Pi coding agent, backed by a memini service.",
|
|
5
5
|
"files": [
|
|
6
6
|
"dist"
|
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
"typecheck": "tsc -p tsconfig.test.json"
|
|
13
13
|
},
|
|
14
14
|
"dependencies": {
|
|
15
|
+
"@memini/namespace-resolver": "workspace:*",
|
|
15
16
|
"typebox": "^1.1.38"
|
|
16
17
|
},
|
|
17
18
|
"devDependencies": {
|