@rvboris/opencode-mempalace 0.2.0 → 0.2.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.
|
@@ -8,17 +8,18 @@ from pathlib import Path
|
|
|
8
8
|
|
|
9
9
|
from mempalace.config import MempalaceConfig
|
|
10
10
|
from mempalace.convo_miner import mine_convos
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
)
|
|
11
|
+
import mempalace.mcp_server as mcp_server
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
restore_stdout = getattr(mcp_server, "_restore_stdout", None)
|
|
15
|
+
if callable(restore_stdout):
|
|
16
|
+
restore_stdout()
|
|
17
17
|
|
|
18
18
|
|
|
19
19
|
def write_result(result: dict) -> None:
|
|
20
20
|
output = json.dumps(result, ensure_ascii=False)
|
|
21
21
|
sys.stdout.buffer.write(output.encode("utf-8", errors="replace"))
|
|
22
|
+
sys.stdout.buffer.flush()
|
|
22
23
|
|
|
23
24
|
|
|
24
25
|
def main() -> int:
|
|
@@ -27,21 +28,21 @@ def main() -> int:
|
|
|
27
28
|
|
|
28
29
|
mode = payload["mode"]
|
|
29
30
|
if mode == "search":
|
|
30
|
-
result = tool_search(
|
|
31
|
+
result = mcp_server.tool_search(
|
|
31
32
|
query=payload["query"],
|
|
32
33
|
limit=payload.get("limit", 5),
|
|
33
34
|
wing=payload.get("wing"),
|
|
34
35
|
room=payload.get("room"),
|
|
35
36
|
)
|
|
36
37
|
elif mode == "save":
|
|
37
|
-
result = tool_add_drawer(
|
|
38
|
+
result = mcp_server.tool_add_drawer(
|
|
38
39
|
wing=payload["wing"],
|
|
39
40
|
room=payload["room"],
|
|
40
41
|
content=payload["content"],
|
|
41
42
|
added_by=payload.get("added_by", "opencode"),
|
|
42
43
|
)
|
|
43
44
|
elif mode == "kg_add":
|
|
44
|
-
result = tool_kg_add(
|
|
45
|
+
result = mcp_server.tool_kg_add(
|
|
45
46
|
subject=payload["subject"],
|
|
46
47
|
predicate=payload["predicate"],
|
|
47
48
|
object=payload["object"],
|
|
@@ -49,7 +50,7 @@ def main() -> int:
|
|
|
49
50
|
source_closet=payload.get("source_closet", ""),
|
|
50
51
|
)
|
|
51
52
|
elif mode == "diary_write":
|
|
52
|
-
result = tool_diary_write(
|
|
53
|
+
result = mcp_server.tool_diary_write(
|
|
53
54
|
agent_name=payload["agent_name"],
|
|
54
55
|
entry=payload["entry"],
|
|
55
56
|
topic=payload.get("topic", "autosave"),
|
|
@@ -17,12 +17,18 @@ const getAdapterTimeoutMs = () => {
|
|
|
17
17
|
const isAdapterResponse = (value) => {
|
|
18
18
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
19
19
|
};
|
|
20
|
+
const getStderrSnippet = (value) => {
|
|
21
|
+
const normalized = value.trim();
|
|
22
|
+
if (!normalized)
|
|
23
|
+
return "";
|
|
24
|
+
return normalized.length > 240 ? `${normalized.slice(0, 240)}...` : normalized;
|
|
25
|
+
};
|
|
20
26
|
export const executeAdapter = async (_shell, payload, retries = 3) => {
|
|
21
27
|
let lastError;
|
|
22
28
|
const timeoutMs = getAdapterTimeoutMs();
|
|
23
29
|
for (let attempt = 0; attempt <= retries; attempt += 1) {
|
|
24
30
|
try {
|
|
25
|
-
const
|
|
31
|
+
const { stderrText, stdoutText } = await new Promise((resolve, reject) => {
|
|
26
32
|
const child = spawn(getPythonCommand(), [getAdapterPath()], {
|
|
27
33
|
stdio: ["pipe", "pipe", "pipe"],
|
|
28
34
|
});
|
|
@@ -48,17 +54,25 @@ export const executeAdapter = async (_shell, payload, retries = 3) => {
|
|
|
48
54
|
child.on("error", (error) => finish(() => reject(error)));
|
|
49
55
|
child.on("close", (code) => {
|
|
50
56
|
finish(() => {
|
|
57
|
+
const stderrText = Buffer.concat(stderr).toString("utf8");
|
|
58
|
+
const stdoutText = Buffer.concat(stdout).toString("utf8");
|
|
51
59
|
if (code === 0) {
|
|
52
|
-
resolve(
|
|
60
|
+
resolve({ stderrText, stdoutText });
|
|
53
61
|
return;
|
|
54
62
|
}
|
|
55
|
-
reject(new Error(
|
|
63
|
+
reject(new Error(stderrText || `Adapter exited with code ${code}`));
|
|
56
64
|
});
|
|
57
65
|
});
|
|
58
66
|
child.stdin.write(JSON.stringify(payload), "utf8");
|
|
59
67
|
child.stdin.end();
|
|
60
68
|
});
|
|
61
|
-
|
|
69
|
+
if (!stdoutText.trim()) {
|
|
70
|
+
const stderrSnippet = getStderrSnippet(stderrText);
|
|
71
|
+
throw new Error(stderrSnippet
|
|
72
|
+
? `${TOOL_ERROR_MESSAGES.emptyAdapterStdout}: ${stderrSnippet}`
|
|
73
|
+
: TOOL_ERROR_MESSAGES.emptyAdapterStdout);
|
|
74
|
+
}
|
|
75
|
+
const parsed = JSON.parse(stdoutText);
|
|
62
76
|
if (!isAdapterResponse(parsed)) {
|
|
63
77
|
throw new Error(TOOL_ERROR_MESSAGES.invalidAdapterPayload);
|
|
64
78
|
}
|
|
@@ -37,6 +37,7 @@ export declare const TOOL_DESCRIPTIONS: {
|
|
|
37
37
|
export declare const TOOL_ERROR_MESSAGES: {
|
|
38
38
|
readonly directMutationBlocked: "Use mempalace_memory instead of direct MemPalace mutation tools";
|
|
39
39
|
readonly invalidAdapterPayload: "Adapter returned an invalid JSON payload";
|
|
40
|
+
readonly emptyAdapterStdout: "Adapter returned empty stdout";
|
|
40
41
|
readonly adapterTimedOut: "Adapter execution timed out";
|
|
41
42
|
};
|
|
42
43
|
export declare const LOG_MESSAGES: {
|
|
@@ -44,6 +44,7 @@ export const TOOL_DESCRIPTIONS = {
|
|
|
44
44
|
export const TOOL_ERROR_MESSAGES = {
|
|
45
45
|
directMutationBlocked: "Use mempalace_memory instead of direct MemPalace mutation tools",
|
|
46
46
|
invalidAdapterPayload: "Adapter returned an invalid JSON payload",
|
|
47
|
+
emptyAdapterStdout: "Adapter returned empty stdout",
|
|
47
48
|
adapterTimedOut: "Adapter execution timed out",
|
|
48
49
|
};
|
|
49
50
|
export const LOG_MESSAGES = {
|
package/package.json
CHANGED