@rvboris/opencode-mempalace 0.1.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.
- package/README.md +114 -158
- package/README.ru.md +115 -159
- package/dist/bridge/mempalace_adapter.py +73 -40
- package/dist/plugin/hooks/event.d.ts +3 -10
- package/dist/plugin/hooks/event.js +77 -44
- package/dist/plugin/hooks/system.d.ts +5 -7
- package/dist/plugin/hooks/system.js +16 -19
- package/dist/plugin/hooks/tool.d.ts +2 -10
- package/dist/plugin/hooks/tool.js +4 -49
- package/dist/plugin/index.js +0 -2
- package/dist/plugin/lib/adapter.d.ts +2 -1
- package/dist/plugin/lib/adapter.js +56 -9
- package/dist/plugin/lib/autosave.d.ts +16 -21
- package/dist/plugin/lib/autosave.js +47 -101
- package/dist/plugin/lib/config.d.ts +4 -3
- package/dist/plugin/lib/config.js +58 -19
- package/dist/plugin/lib/constants.d.ts +81 -0
- package/dist/plugin/lib/constants.js +88 -0
- package/dist/plugin/lib/context.js +17 -16
- package/dist/plugin/lib/enforcement.js +2 -8
- package/dist/plugin/lib/log.d.ts +2 -7
- package/dist/plugin/lib/log.js +3 -2
- package/dist/plugin/lib/opencode.d.ts +5 -0
- package/dist/plugin/lib/opencode.js +16 -0
- package/dist/plugin/lib/scope.d.ts +2 -2
- package/dist/plugin/lib/scope.js +3 -2
- package/dist/plugin/lib/types.d.ts +79 -0
- package/dist/plugin/lib/types.js +15 -0
- package/dist/plugin/tools/mempalace-memory.d.ts +4 -8
- package/dist/plugin/tools/mempalace-memory.js +31 -23
- package/package.json +11 -2
- package/dist/plugin/hooks/chat-params.d.ts +0 -5
- package/dist/plugin/hooks/chat-params.js +0 -8
|
@@ -1,37 +1,38 @@
|
|
|
1
1
|
import { getProjectScope, getUserScope } from "./scope";
|
|
2
|
+
import { INSTRUCTION_TEXT } from "./constants";
|
|
2
3
|
export const buildRetrievalInstruction = ({ projectName, projectWingPrefix, userWingPrefix, maxInjectedItems, retrievalQueryLimit, lastUserMessage, }) => {
|
|
3
4
|
const project = getProjectScope(projectName, projectWingPrefix);
|
|
4
5
|
const user = getUserScope(userWingPrefix);
|
|
5
6
|
return [
|
|
6
|
-
|
|
7
|
+
INSTRUCTION_TEXT.retrievalIntro,
|
|
7
8
|
`Query focus: ${lastUserMessage.slice(0, 500)}`,
|
|
8
9
|
`Limit search results to ${retrievalQueryLimit} per scope.`,
|
|
9
10
|
`Search user memory in wing ${user.wing} across rooms ${user.rooms.join(", ")}.`,
|
|
10
11
|
`Search project memory in wing ${project.wing} across rooms ${project.rooms.join(", ")}.`,
|
|
11
12
|
`Use concise relevant memories only, up to ${maxInjectedItems} items total.`,
|
|
12
|
-
|
|
13
|
+
INSTRUCTION_TEXT.doNotMentionToUser,
|
|
13
14
|
].join(" ");
|
|
14
15
|
};
|
|
15
16
|
export const buildAutosaveInstruction = (reason) => {
|
|
16
17
|
return [
|
|
17
|
-
|
|
18
|
-
|
|
18
|
+
INSTRUCTION_TEXT.autosaveIntro,
|
|
19
|
+
INSTRUCTION_TEXT.avoidRawMutationTools,
|
|
19
20
|
`Trigger reason: ${reason}.`,
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
21
|
+
INSTRUCTION_TEXT.saveStableFacts,
|
|
22
|
+
INSTRUCTION_TEXT.preferConciseStructuredMemories,
|
|
23
|
+
INSTRUCTION_TEXT.userScopeHint,
|
|
24
|
+
INSTRUCTION_TEXT.projectScopeHint,
|
|
25
|
+
INSTRUCTION_TEXT.avoidFullTranscript,
|
|
26
|
+
INSTRUCTION_TEXT.applyPrivacyRedaction,
|
|
27
|
+
INSTRUCTION_TEXT.doNotMentionToUser,
|
|
27
28
|
].join(" ");
|
|
28
29
|
};
|
|
29
30
|
export const buildKeywordSaveInstruction = () => {
|
|
30
31
|
return [
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
32
|
+
INSTRUCTION_TEXT.keywordIntro,
|
|
33
|
+
INSTRUCTION_TEXT.useMemoryToolNow,
|
|
34
|
+
INSTRUCTION_TEXT.avoidRawMutationTools,
|
|
35
|
+
INSTRUCTION_TEXT.chooseScope,
|
|
36
|
+
INSTRUCTION_TEXT.doNotMentionToUser,
|
|
36
37
|
].join(" ");
|
|
37
38
|
};
|
|
@@ -1,10 +1,4 @@
|
|
|
1
|
+
import { DIRECT_MEMPALACE_MUTATION_TOOLS } from "./constants";
|
|
1
2
|
export const isDirectMempalaceMutationTool = (tool) => {
|
|
2
|
-
return
|
|
3
|
-
"mempalace_add_drawer",
|
|
4
|
-
"mempalace_kg_add",
|
|
5
|
-
"mempalace_diary_write",
|
|
6
|
-
"mcp-router_mempalace_add_drawer",
|
|
7
|
-
"mcp-router_mempalace_kg_add",
|
|
8
|
-
"mcp-router_mempalace_diary_write",
|
|
9
|
-
].includes(tool);
|
|
3
|
+
return DIRECT_MEMPALACE_MUTATION_TOOLS.includes(tool);
|
|
10
4
|
};
|
package/dist/plugin/lib/log.d.ts
CHANGED
|
@@ -1,11 +1,6 @@
|
|
|
1
|
+
import type { AppLoggerClient } from "./types";
|
|
1
2
|
type LogLevel = "INFO" | "WARN" | "ERROR";
|
|
2
|
-
export declare const setLogger: (client:
|
|
3
|
-
app?: {
|
|
4
|
-
log?: (input: {
|
|
5
|
-
body: any;
|
|
6
|
-
}) => Promise<unknown>;
|
|
7
|
-
};
|
|
8
|
-
}) => void;
|
|
3
|
+
export declare const setLogger: (client: AppLoggerClient) => void;
|
|
9
4
|
export declare const resetLogger: () => void;
|
|
10
5
|
export declare const writeLog: (level: LogLevel, message: string, details?: Record<string, unknown>) => Promise<void>;
|
|
11
6
|
export {};
|
package/dist/plugin/lib/log.js
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import fs from "node:fs/promises";
|
|
2
2
|
import os from "node:os";
|
|
3
3
|
import path from "node:path";
|
|
4
|
+
import { ENV_KEYS, LOG_FILE_NAME, SERVICE_NAME } from "./constants";
|
|
4
5
|
let logger = async () => { };
|
|
5
6
|
const getFileLogPath = () => {
|
|
6
|
-
return process.env.
|
|
7
|
+
return process.env[ENV_KEYS.autosaveLogFile] || path.join(os.homedir(), ".mempalace", LOG_FILE_NAME);
|
|
7
8
|
};
|
|
8
9
|
const writeFileLog = async (level, message, details) => {
|
|
9
10
|
try {
|
|
@@ -28,7 +29,7 @@ export const setLogger = (client) => {
|
|
|
28
29
|
try {
|
|
29
30
|
await client.app?.log?.({
|
|
30
31
|
body: {
|
|
31
|
-
service:
|
|
32
|
+
service: SERVICE_NAME,
|
|
32
33
|
level: toAppLevel(level),
|
|
33
34
|
message,
|
|
34
35
|
extra: details,
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { PluginInput } from "@opencode-ai/plugin";
|
|
2
|
+
import type { MessageLike, SessionMessagesResponse } from "./types";
|
|
3
|
+
export declare const getProjectName: (project: unknown) => string | undefined;
|
|
4
|
+
export declare const getSessionMessages: (response: SessionMessagesResponse) => readonly MessageLike[];
|
|
5
|
+
export declare const loadSessionMessages: (client: PluginInput["client"], sessionId: string) => Promise<readonly MessageLike[]>;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export const getProjectName = (project) => {
|
|
2
|
+
return typeof project === "object" && project !== null && "name" in project && typeof project.name === "string"
|
|
3
|
+
? project.name
|
|
4
|
+
: undefined;
|
|
5
|
+
};
|
|
6
|
+
export const getSessionMessages = (response) => {
|
|
7
|
+
if (Array.isArray(response))
|
|
8
|
+
return response;
|
|
9
|
+
if (response && typeof response === "object" && "data" in response && Array.isArray(response.data))
|
|
10
|
+
return response.data;
|
|
11
|
+
return [];
|
|
12
|
+
};
|
|
13
|
+
export const loadSessionMessages = async (client, sessionId) => {
|
|
14
|
+
const response = await client.session.messages({ path: { id: sessionId } });
|
|
15
|
+
return getSessionMessages(response);
|
|
16
|
+
};
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
export declare const getProjectScope: (projectName: string | undefined, projectWingPrefix: string) => {
|
|
2
2
|
wing: string;
|
|
3
|
-
rooms:
|
|
3
|
+
rooms: readonly ["architecture", "workflow", "decisions", "bugs", "setup"];
|
|
4
4
|
};
|
|
5
5
|
export declare const getUserScope: (userWingPrefix: string) => {
|
|
6
6
|
wing: string;
|
|
7
|
-
rooms:
|
|
7
|
+
rooms: readonly ["preferences", "workflow", "communication"];
|
|
8
8
|
};
|
package/dist/plugin/lib/scope.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { PROJECT_MEMORY_ROOMS, USER_MEMORY_ROOMS } from "./types";
|
|
1
2
|
const slugify = (value, fallback) => {
|
|
2
3
|
const slug = value.toLowerCase().replace(/[^a-z0-9_-]+/g, "-").replace(/-+/g, "-").replace(/^-|-$/g, "");
|
|
3
4
|
return slug || fallback;
|
|
@@ -5,12 +6,12 @@ const slugify = (value, fallback) => {
|
|
|
5
6
|
export const getProjectScope = (projectName, projectWingPrefix) => {
|
|
6
7
|
return {
|
|
7
8
|
wing: `${projectWingPrefix}_${slugify(projectName || "default", "default")}`,
|
|
8
|
-
rooms:
|
|
9
|
+
rooms: PROJECT_MEMORY_ROOMS,
|
|
9
10
|
};
|
|
10
11
|
};
|
|
11
12
|
export const getUserScope = (userWingPrefix) => {
|
|
12
13
|
return {
|
|
13
14
|
wing: `${userWingPrefix}_profile`,
|
|
14
|
-
rooms:
|
|
15
|
+
rooms: USER_MEMORY_ROOMS,
|
|
15
16
|
};
|
|
16
17
|
};
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import type { PluginInput } from "@opencode-ai/plugin";
|
|
2
|
+
import type { Event, Message, Part } from "@opencode-ai/sdk";
|
|
3
|
+
import { DEFAULT_ROOM, DEFAULT_TOPIC, DEFAULT_AGENT_NAME, DEFAULT_EXTRACT_MODE, DEFAULT_INJECTED_ITEMS, DEFAULT_RETRIEVAL_LIMIT, DEFAULT_LIMIT, DEFAULT_ADAPTER_TIMEOUT_MS, MAX_USER_MESSAGES_DIGEST, MAX_TRANSCRIPT_MESSAGES_DIGEST, DATE_ISO_SLICE, SERVICE_NAME, COMPACTION_CONTEXT_MESSAGE, ERROR_MESSAGES, DEFAULT_USER_WING_PREFIX, DEFAULT_PROJECT_WING_PREFIX, DEFAULT_KEYWORD_PATTERNS, CONFIG_PATH_SEGMENTS, ENV_KEYS, LOG_FILE_NAME, DIRECT_MEMPALACE_MUTATION_TOOLS, TOOL_DESCRIPTIONS, TOOL_ERROR_MESSAGES, LOG_MESSAGES, INSTRUCTION_TEXT } from "./constants";
|
|
4
|
+
export { DEFAULT_ROOM, DEFAULT_TOPIC, DEFAULT_AGENT_NAME, DEFAULT_EXTRACT_MODE, DEFAULT_INJECTED_ITEMS, DEFAULT_RETRIEVAL_LIMIT, DEFAULT_LIMIT, DEFAULT_ADAPTER_TIMEOUT_MS, DEFAULT_USER_WING_PREFIX, DEFAULT_PROJECT_WING_PREFIX, DEFAULT_KEYWORD_PATTERNS, CONFIG_PATH_SEGMENTS, ENV_KEYS, MAX_USER_MESSAGES_DIGEST, MAX_TRANSCRIPT_MESSAGES_DIGEST, DATE_ISO_SLICE, SERVICE_NAME, LOG_FILE_NAME, DIRECT_MEMPALACE_MUTATION_TOOLS, TOOL_DESCRIPTIONS, TOOL_ERROR_MESSAGES, LOG_MESSAGES, INSTRUCTION_TEXT, COMPACTION_CONTEXT_MESSAGE, ERROR_MESSAGES, };
|
|
5
|
+
export declare const MEMORY_SCOPES: readonly ["user", "project"];
|
|
6
|
+
export type MemoryScope = (typeof MEMORY_SCOPES)[number];
|
|
7
|
+
export declare const USER_MEMORY_ROOMS: readonly ["preferences", "workflow", "communication"];
|
|
8
|
+
export declare const PROJECT_MEMORY_ROOMS: readonly ["architecture", "workflow", "decisions", "bugs", "setup"];
|
|
9
|
+
export type KnownMemoryRoom = (typeof USER_MEMORY_ROOMS)[number] | (typeof PROJECT_MEMORY_ROOMS)[number];
|
|
10
|
+
export declare const TOOL_MEMORY_MODES: readonly ["save", "search", "kg_add", "diary_write"];
|
|
11
|
+
export type ToolMemoryMode = (typeof TOOL_MEMORY_MODES)[number];
|
|
12
|
+
export declare const ADAPTER_MODES: readonly ["save", "search", "kg_add", "diary_write", "mine_messages"];
|
|
13
|
+
export type AdapterMode = (typeof ADAPTER_MODES)[number];
|
|
14
|
+
export declare const SESSION_EVENT_TYPES: readonly ["session.idle", "session.compacted", "session.deleted", "session.error", "session.updated", "message.updated"];
|
|
15
|
+
export type SessionEventType = (typeof SESSION_EVENT_TYPES)[number];
|
|
16
|
+
export type AppLogLevel = "info" | "warn" | "error";
|
|
17
|
+
export type MessagePartLike = Part | {
|
|
18
|
+
text?: string;
|
|
19
|
+
content?: string;
|
|
20
|
+
};
|
|
21
|
+
export type MessageInfoLike = Message | {
|
|
22
|
+
role?: string;
|
|
23
|
+
content?: string;
|
|
24
|
+
};
|
|
25
|
+
export type MessageLike = {
|
|
26
|
+
role?: string;
|
|
27
|
+
content?: string;
|
|
28
|
+
parts?: readonly MessagePartLike[];
|
|
29
|
+
info?: MessageInfoLike;
|
|
30
|
+
};
|
|
31
|
+
export type SessionMessagesResponse = Awaited<ReturnType<PluginInput["client"]["session"]["messages"]>> | {
|
|
32
|
+
data?: readonly MessageLike[];
|
|
33
|
+
} | readonly MessageLike[] | null | undefined;
|
|
34
|
+
export type SessionEvent = Event;
|
|
35
|
+
export type AppLoggerClient = PluginInput["client"];
|
|
36
|
+
export type EventHookContext = Pick<PluginInput, "client" | "project" | "directory" | "worktree" | "$">;
|
|
37
|
+
export type SystemHookContext = Pick<PluginInput, "client" | "project">;
|
|
38
|
+
export type ToolContext = Pick<PluginInput, "project" | "$">;
|
|
39
|
+
export type SaveAdapterRequest = {
|
|
40
|
+
mode: "save";
|
|
41
|
+
wing: string;
|
|
42
|
+
room?: string;
|
|
43
|
+
content: string;
|
|
44
|
+
added_by: string;
|
|
45
|
+
};
|
|
46
|
+
export type SearchAdapterRequest = {
|
|
47
|
+
mode: "search";
|
|
48
|
+
query: string;
|
|
49
|
+
wing: string;
|
|
50
|
+
room?: string;
|
|
51
|
+
limit?: number;
|
|
52
|
+
};
|
|
53
|
+
export type KgAddAdapterRequest = {
|
|
54
|
+
mode: "kg_add";
|
|
55
|
+
subject: string;
|
|
56
|
+
predicate: string;
|
|
57
|
+
object: string;
|
|
58
|
+
valid_from: string;
|
|
59
|
+
source_closet: string;
|
|
60
|
+
};
|
|
61
|
+
export type DiaryWriteAdapterRequest = {
|
|
62
|
+
mode: "diary_write";
|
|
63
|
+
agent_name?: string;
|
|
64
|
+
entry: string;
|
|
65
|
+
topic?: string;
|
|
66
|
+
};
|
|
67
|
+
export type MineMessagesAdapterRequest = {
|
|
68
|
+
mode: "mine_messages";
|
|
69
|
+
transcript: string;
|
|
70
|
+
wing: string;
|
|
71
|
+
extract_mode: string;
|
|
72
|
+
agent: string;
|
|
73
|
+
};
|
|
74
|
+
export type AdapterRequest = SaveAdapterRequest | SearchAdapterRequest | KgAddAdapterRequest | DiaryWriteAdapterRequest | MineMessagesAdapterRequest;
|
|
75
|
+
export type AdapterResponse = {
|
|
76
|
+
success?: boolean;
|
|
77
|
+
error?: string;
|
|
78
|
+
[key: string]: unknown;
|
|
79
|
+
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { DEFAULT_ROOM, DEFAULT_TOPIC, DEFAULT_AGENT_NAME, DEFAULT_EXTRACT_MODE, DEFAULT_INJECTED_ITEMS, DEFAULT_RETRIEVAL_LIMIT, DEFAULT_LIMIT, DEFAULT_ADAPTER_TIMEOUT_MS, MAX_USER_MESSAGES_DIGEST, MAX_TRANSCRIPT_MESSAGES_DIGEST, DATE_ISO_SLICE, SERVICE_NAME, COMPACTION_CONTEXT_MESSAGE, ERROR_MESSAGES, DEFAULT_USER_WING_PREFIX, DEFAULT_PROJECT_WING_PREFIX, DEFAULT_KEYWORD_PATTERNS, CONFIG_PATH_SEGMENTS, ENV_KEYS, LOG_FILE_NAME, DIRECT_MEMPALACE_MUTATION_TOOLS, TOOL_DESCRIPTIONS, TOOL_ERROR_MESSAGES, LOG_MESSAGES, INSTRUCTION_TEXT, } from "./constants";
|
|
2
|
+
export { DEFAULT_ROOM, DEFAULT_TOPIC, DEFAULT_AGENT_NAME, DEFAULT_EXTRACT_MODE, DEFAULT_INJECTED_ITEMS, DEFAULT_RETRIEVAL_LIMIT, DEFAULT_LIMIT, DEFAULT_ADAPTER_TIMEOUT_MS, DEFAULT_USER_WING_PREFIX, DEFAULT_PROJECT_WING_PREFIX, DEFAULT_KEYWORD_PATTERNS, CONFIG_PATH_SEGMENTS, ENV_KEYS, MAX_USER_MESSAGES_DIGEST, MAX_TRANSCRIPT_MESSAGES_DIGEST, DATE_ISO_SLICE, SERVICE_NAME, LOG_FILE_NAME, DIRECT_MEMPALACE_MUTATION_TOOLS, TOOL_DESCRIPTIONS, TOOL_ERROR_MESSAGES, LOG_MESSAGES, INSTRUCTION_TEXT, COMPACTION_CONTEXT_MESSAGE, ERROR_MESSAGES, };
|
|
3
|
+
export const MEMORY_SCOPES = ["user", "project"];
|
|
4
|
+
export const USER_MEMORY_ROOMS = ["preferences", "workflow", "communication"];
|
|
5
|
+
export const PROJECT_MEMORY_ROOMS = ["architecture", "workflow", "decisions", "bugs", "setup"];
|
|
6
|
+
export const TOOL_MEMORY_MODES = ["save", "search", "kg_add", "diary_write"];
|
|
7
|
+
export const ADAPTER_MODES = ["save", "search", "kg_add", "diary_write", "mine_messages"];
|
|
8
|
+
export const SESSION_EVENT_TYPES = [
|
|
9
|
+
"session.idle",
|
|
10
|
+
"session.compacted",
|
|
11
|
+
"session.deleted",
|
|
12
|
+
"session.error",
|
|
13
|
+
"session.updated",
|
|
14
|
+
"message.updated",
|
|
15
|
+
];
|
|
@@ -1,13 +1,10 @@
|
|
|
1
|
-
type
|
|
2
|
-
|
|
3
|
-
$: any;
|
|
4
|
-
};
|
|
5
|
-
export declare const mempalaceMemoryTool: (ctx: PluginContext) => {
|
|
1
|
+
import { type ToolContext } from "../lib/types";
|
|
2
|
+
export declare const mempalaceMemoryTool: (ctx: ToolContext) => {
|
|
6
3
|
description: string;
|
|
7
4
|
args: {
|
|
8
5
|
mode: import("zod").ZodEnum<{
|
|
9
|
-
search: "search";
|
|
10
6
|
save: "save";
|
|
7
|
+
search: "search";
|
|
11
8
|
kg_add: "kg_add";
|
|
12
9
|
diary_write: "diary_write";
|
|
13
10
|
}>;
|
|
@@ -26,7 +23,7 @@ export declare const mempalaceMemoryTool: (ctx: PluginContext) => {
|
|
|
26
23
|
limit: import("zod").ZodDefault<import("zod").ZodOptional<import("zod").ZodNumber>>;
|
|
27
24
|
};
|
|
28
25
|
execute(args: {
|
|
29
|
-
mode: "
|
|
26
|
+
mode: "save" | "search" | "kg_add" | "diary_write";
|
|
30
27
|
scope: "user" | "project";
|
|
31
28
|
room: string;
|
|
32
29
|
topic: string;
|
|
@@ -39,4 +36,3 @@ export declare const mempalaceMemoryTool: (ctx: PluginContext) => {
|
|
|
39
36
|
object?: string | undefined;
|
|
40
37
|
}, context: import("@opencode-ai/plugin").ToolContext): Promise<string>;
|
|
41
38
|
};
|
|
42
|
-
export {};
|
|
@@ -2,8 +2,11 @@ import { tool } from "@opencode-ai/plugin";
|
|
|
2
2
|
import { executeAdapter } from "../lib/adapter";
|
|
3
3
|
import { loadConfig } from "../lib/config";
|
|
4
4
|
import { sanitizeText } from "../lib/derive";
|
|
5
|
+
import { DATE_ISO_SLICE, DEFAULT_AGENT_NAME, DEFAULT_LIMIT, DEFAULT_ROOM, DEFAULT_TOPIC, ERROR_MESSAGES, TOOL_DESCRIPTIONS } from "../lib/constants";
|
|
6
|
+
import { getProjectName } from "../lib/opencode";
|
|
5
7
|
import { isFullyPrivate, redactSecrets } from "../lib/privacy";
|
|
6
8
|
import { getProjectScope, getUserScope } from "../lib/scope";
|
|
9
|
+
import { MEMORY_SCOPES, TOOL_MEMORY_MODES } from "../lib/types";
|
|
7
10
|
const getProjectWing = (projectName, prefix) => {
|
|
8
11
|
return getProjectScope(projectName, prefix).wing;
|
|
9
12
|
};
|
|
@@ -17,47 +20,49 @@ const normalizeValue = (value, redact) => {
|
|
|
17
20
|
return redact ? redactSecrets(sanitized) : sanitized;
|
|
18
21
|
};
|
|
19
22
|
export const mempalaceMemoryTool = (ctx) => tool({
|
|
20
|
-
description:
|
|
23
|
+
description: TOOL_DESCRIPTIONS.mempalaceMemory,
|
|
21
24
|
args: {
|
|
22
|
-
mode: tool.schema.enum([
|
|
23
|
-
scope: tool.schema.enum([
|
|
24
|
-
room: tool.schema.string().optional().default(
|
|
25
|
+
mode: tool.schema.enum([...TOOL_MEMORY_MODES]),
|
|
26
|
+
scope: tool.schema.enum([...MEMORY_SCOPES]).optional().default("project"),
|
|
27
|
+
room: tool.schema.string().optional().default(DEFAULT_ROOM),
|
|
25
28
|
content: tool.schema.string().optional(),
|
|
26
29
|
query: tool.schema.string().optional(),
|
|
27
30
|
subject: tool.schema.string().optional(),
|
|
28
31
|
predicate: tool.schema.string().optional(),
|
|
29
32
|
object: tool.schema.string().optional(),
|
|
30
|
-
topic: tool.schema.string().optional().default(
|
|
31
|
-
agent_name: tool.schema.string().optional().default(
|
|
32
|
-
limit: tool.schema.number().optional().default(
|
|
33
|
+
topic: tool.schema.string().optional().default(DEFAULT_TOPIC),
|
|
34
|
+
agent_name: tool.schema.string().optional().default(DEFAULT_AGENT_NAME),
|
|
35
|
+
limit: tool.schema.number().optional().default(DEFAULT_LIMIT),
|
|
33
36
|
},
|
|
34
37
|
async execute(args) {
|
|
35
38
|
const config = await loadConfig();
|
|
36
|
-
const
|
|
39
|
+
const scope = args.scope ?? "project";
|
|
40
|
+
const wing = scope === "user"
|
|
37
41
|
? getUserWing(config.userWingPrefix)
|
|
38
|
-
: getProjectWing(ctx.project
|
|
42
|
+
: getProjectWing(getProjectName(ctx.project), config.projectWingPrefix);
|
|
39
43
|
if (args.mode === "save") {
|
|
40
44
|
if (!args.content)
|
|
41
|
-
return JSON.stringify({ success: false, error:
|
|
45
|
+
return JSON.stringify({ success: false, error: ERROR_MESSAGES.contentRequired });
|
|
42
46
|
if (isFullyPrivate(args.content)) {
|
|
43
|
-
return JSON.stringify({ success: false, error:
|
|
47
|
+
return JSON.stringify({ success: false, error: ERROR_MESSAGES.fullyPrivate });
|
|
44
48
|
}
|
|
45
|
-
const content = normalizeValue(args.content, config.privacyRedactionEnabled);
|
|
49
|
+
const content = normalizeValue(args.content, config.privacyRedactionEnabled) ?? "";
|
|
46
50
|
const result = await executeAdapter(ctx.$, {
|
|
47
51
|
mode: "save",
|
|
48
52
|
wing,
|
|
49
53
|
room: normalizeValue(args.room, false),
|
|
50
54
|
content,
|
|
51
|
-
added_by:
|
|
55
|
+
added_by: DEFAULT_AGENT_NAME,
|
|
52
56
|
});
|
|
53
57
|
return JSON.stringify(result);
|
|
54
58
|
}
|
|
55
59
|
if (args.mode === "search") {
|
|
56
60
|
if (!args.query)
|
|
57
|
-
return JSON.stringify({ success: false, error:
|
|
61
|
+
return JSON.stringify({ success: false, error: ERROR_MESSAGES.queryRequired });
|
|
62
|
+
const query = normalizeValue(args.query, config.privacyRedactionEnabled) ?? "";
|
|
58
63
|
const result = await executeAdapter(ctx.$, {
|
|
59
64
|
mode: "search",
|
|
60
|
-
query
|
|
65
|
+
query,
|
|
61
66
|
wing,
|
|
62
67
|
room: normalizeValue(args.room, false),
|
|
63
68
|
limit: args.limit,
|
|
@@ -66,23 +71,26 @@ export const mempalaceMemoryTool = (ctx) => tool({
|
|
|
66
71
|
}
|
|
67
72
|
if (args.mode === "kg_add") {
|
|
68
73
|
if (!args.subject || !args.predicate || !args.object) {
|
|
69
|
-
return JSON.stringify({ success: false, error:
|
|
74
|
+
return JSON.stringify({ success: false, error: ERROR_MESSAGES.fieldsRequired });
|
|
70
75
|
}
|
|
76
|
+
const subject = normalizeValue(args.subject, config.privacyRedactionEnabled) ?? "";
|
|
77
|
+
const predicate = normalizeValue(args.predicate, false) ?? "";
|
|
78
|
+
const object = normalizeValue(args.object, config.privacyRedactionEnabled) ?? "";
|
|
71
79
|
const result = await executeAdapter(ctx.$, {
|
|
72
80
|
mode: "kg_add",
|
|
73
|
-
subject
|
|
74
|
-
predicate
|
|
75
|
-
object
|
|
76
|
-
valid_from: new Date().toISOString().slice(0,
|
|
81
|
+
subject,
|
|
82
|
+
predicate,
|
|
83
|
+
object,
|
|
84
|
+
valid_from: new Date().toISOString().slice(0, DATE_ISO_SLICE),
|
|
77
85
|
source_closet: "",
|
|
78
86
|
});
|
|
79
87
|
return JSON.stringify(result);
|
|
80
88
|
}
|
|
81
89
|
const result = await executeAdapter(ctx.$, {
|
|
82
90
|
mode: "diary_write",
|
|
83
|
-
agent_name: normalizeValue(args.agent_name, false),
|
|
84
|
-
entry: normalizeValue(args.content || "", config.privacyRedactionEnabled),
|
|
85
|
-
topic: normalizeValue(args.topic, false),
|
|
91
|
+
agent_name: normalizeValue(args.agent_name, false) ?? DEFAULT_AGENT_NAME,
|
|
92
|
+
entry: normalizeValue(args.content || "", config.privacyRedactionEnabled) ?? "",
|
|
93
|
+
topic: normalizeValue(args.topic, false) ?? DEFAULT_TOPIC,
|
|
86
94
|
});
|
|
87
95
|
return JSON.stringify(result);
|
|
88
96
|
},
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rvboris/opencode-mempalace",
|
|
3
|
-
"version": "0.1
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"description": "OpenCode plugin for hidden MemPalace retrieval and autosave via a local Python adapter.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/plugin/index.js",
|
|
@@ -25,10 +25,15 @@
|
|
|
25
25
|
"memory"
|
|
26
26
|
],
|
|
27
27
|
"license": "MIT",
|
|
28
|
+
"repository": {
|
|
29
|
+
"type": "git",
|
|
30
|
+
"url": "git+https://github.com/rvboris/opencode-mempalace.git"
|
|
31
|
+
},
|
|
28
32
|
"peerDependencies": {
|
|
29
33
|
"@opencode-ai/plugin": "^1.4.0"
|
|
30
34
|
},
|
|
31
35
|
"devDependencies": {
|
|
36
|
+
"@biomejs/biome": "^2.4.12",
|
|
32
37
|
"@opencode-ai/plugin": "^1.4.0",
|
|
33
38
|
"@types/bun": "^1.3.0",
|
|
34
39
|
"@types/node": "^22.13.9",
|
|
@@ -36,8 +41,12 @@
|
|
|
36
41
|
},
|
|
37
42
|
"scripts": {
|
|
38
43
|
"build": "node scripts/build.mjs",
|
|
44
|
+
"lint": "biome lint plugin tests scripts package.json tsconfig.json example-opencode.json biome.json",
|
|
45
|
+
"lint:ci": "biome lint plugin tests scripts package.json tsconfig.json example-opencode.json biome.json",
|
|
39
46
|
"prepublishOnly": "npm run build",
|
|
40
|
-
"test": "bun test"
|
|
47
|
+
"test": "bun test",
|
|
48
|
+
"test:coverage": "bun test --coverage --coverage-reporter=text --coverage-reporter=lcov",
|
|
49
|
+
"typecheck": "tsc -p tsconfig.json --noEmit"
|
|
41
50
|
},
|
|
42
51
|
"publishConfig": {
|
|
43
52
|
"access": "public"
|