opencode-remote-agent-memory 0.1.0 → 0.1.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 +2 -2
- package/package.json +2 -1
- package/src/letta.ts +9 -10
- package/src/plugin.ts +3 -45
package/README.md
CHANGED
|
@@ -69,6 +69,6 @@ Restart OpenCode.
|
|
|
69
69
|
git clone https://github.com/davidhidvegi/opencode-remote-agent-memory.git
|
|
70
70
|
|
|
71
71
|
# Link the client to OpenCode
|
|
72
|
-
mkdir -p ~/.config/opencode/
|
|
73
|
-
ln -sf "$(pwd)/client/src/plugin.ts" ~/.config/opencode/
|
|
72
|
+
mkdir -p ~/.config/opencode/plugins
|
|
73
|
+
ln -sf "$(pwd)/client/src/plugin.ts" ~/.config/opencode/plugins/memory.ts
|
|
74
74
|
```
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "opencode-remote-agent-memory",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"description": "Letta-style editable remote memory blocks for OpenCode.",
|
|
5
5
|
"author": "David Hidvegi <david@hidvegi.xyz>",
|
|
6
6
|
"license": "MIT",
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
"type": "git",
|
|
9
9
|
"url": "git+https://github.com/davidhidvegi/opencode-remote-agent-memory.git"
|
|
10
10
|
},
|
|
11
|
+
"main": "src/plugin.ts",
|
|
11
12
|
"type": "module",
|
|
12
13
|
"files": [
|
|
13
14
|
"src"
|
package/src/letta.ts
CHANGED
|
@@ -31,7 +31,7 @@ Memory blocks are limited in size. Check the chars_current and chars_limit in ea
|
|
|
31
31
|
|
|
32
32
|
<memory_scopes>
|
|
33
33
|
Memory blocks have four scopes:
|
|
34
|
-
- global: Shared across all projects. Use for general facts and information that applies everywhere.
|
|
34
|
+
- global: Shared across all users and projects. Use for general facts and information that applies everywhere.
|
|
35
35
|
- user: Specific to the user. Use for user preferences, habits, constraints, and personal details. The user is inferred from your API key.
|
|
36
36
|
- project: Specific to the current project (as configured). Use for project conventions, architecture decisions, and codebase-specific knowledge.
|
|
37
37
|
- domain: Specific domain knowledge (e.g., Elixir, Python, debugging). NOT automatically injected - retrieve on-demand using memory_list with scope="domain" when you need domain-specific knowledge.
|
|
@@ -39,16 +39,15 @@ Memory blocks have four scopes:
|
|
|
39
39
|
</memory_instructions>`;
|
|
40
40
|
|
|
41
41
|
export const DEFAULT_DESCRIPTIONS: Record<string, string> = {
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
project:
|
|
47
|
-
"The project block: Stores durable, high-signal information about this codebase: commands, architecture notes, conventions, and gotchas.",
|
|
48
|
-
domain:
|
|
49
|
-
"The domain block: Stores specific domain knowledge (e.g., Elixir, Python, debugging techniques). Retrieved on-demand when you need specialized knowledge.",
|
|
42
|
+
global: "",
|
|
43
|
+
user: "",
|
|
44
|
+
project: "",
|
|
45
|
+
domain: "",
|
|
50
46
|
};
|
|
51
47
|
|
|
52
48
|
export function getDefaultDescription(label: string): string {
|
|
53
|
-
return
|
|
49
|
+
return (
|
|
50
|
+
DEFAULT_DESCRIPTIONS[label] ??
|
|
51
|
+
"Durable memory block. Keep this concise and high-signal."
|
|
52
|
+
);
|
|
54
53
|
}
|
package/src/plugin.ts
CHANGED
|
@@ -1,11 +1,7 @@
|
|
|
1
1
|
import type { Plugin, ToolDefinition } from "@opencode-ai/plugin";
|
|
2
2
|
|
|
3
|
-
import {
|
|
4
|
-
buildJournalSystemNote,
|
|
5
|
-
loadConfig,
|
|
6
|
-
} from "./journal";
|
|
3
|
+
import { buildJournalSystemNote, loadConfig } from "./journal";
|
|
7
4
|
import { createRemoteMemoryStore, createRemoteJournalStore } from "./remote";
|
|
8
|
-
import type { MemoryError } from "./remote";
|
|
9
5
|
import { renderMemoryBlocks } from "./prompt";
|
|
10
6
|
import {
|
|
11
7
|
JournalRead,
|
|
@@ -18,29 +14,6 @@ import {
|
|
|
18
14
|
} from "./tools";
|
|
19
15
|
import type { JournalContext } from "./tools";
|
|
20
16
|
|
|
21
|
-
function getSystemErrorWarning(error: MemoryError | null): string {
|
|
22
|
-
if (!error) return "";
|
|
23
|
-
|
|
24
|
-
switch (error.code) {
|
|
25
|
-
case "CONNECTION_ERROR":
|
|
26
|
-
return `\n\n<memory_warning>
|
|
27
|
-
⚠️ Memory server unavailable. Memories cannot be loaded. Please check that the memory server is running.
|
|
28
|
-
</memory_warning>`;
|
|
29
|
-
case "AUTH_ERROR":
|
|
30
|
-
return `\n\n<memory_warning>
|
|
31
|
-
⚠️ Memory authentication failed. Check your API key configuration.
|
|
32
|
-
</memory_warning>`;
|
|
33
|
-
case "FORBIDDEN":
|
|
34
|
-
return `\n\n<memory_warning>
|
|
35
|
-
⚠️ Memory permission denied. ${error.message}
|
|
36
|
-
</memory_warning>`;
|
|
37
|
-
default:
|
|
38
|
-
return `\n\n<memory_warning>
|
|
39
|
-
⚠️ Memory error: ${error.message}
|
|
40
|
-
</memory_warning>`;
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
|
|
44
17
|
export const MemoryPlugin: Plugin = async (input) => {
|
|
45
18
|
const directory = (input as { directory?: string }).directory ?? "";
|
|
46
19
|
const config = await loadConfig(directory);
|
|
@@ -48,7 +21,7 @@ export const MemoryPlugin: Plugin = async (input) => {
|
|
|
48
21
|
const store = createRemoteMemoryStore(
|
|
49
22
|
config.remote.url!,
|
|
50
23
|
config.remote.apiKey!,
|
|
51
|
-
config.remote.project
|
|
24
|
+
config.remote.project!,
|
|
52
25
|
);
|
|
53
26
|
|
|
54
27
|
const journalEnabled = config.journal?.enabled === true;
|
|
@@ -66,7 +39,7 @@ export const MemoryPlugin: Plugin = async (input) => {
|
|
|
66
39
|
if (journalEnabled) {
|
|
67
40
|
const journalStore = createRemoteJournalStore(
|
|
68
41
|
config.remote.url!,
|
|
69
|
-
config.remote.apiKey
|
|
42
|
+
config.remote.apiKey!,
|
|
70
43
|
);
|
|
71
44
|
journalTools = {
|
|
72
45
|
journal_write: JournalWrite(journalStore, journalCtx),
|
|
@@ -86,17 +59,7 @@ export const MemoryPlugin: Plugin = async (input) => {
|
|
|
86
59
|
|
|
87
60
|
"experimental.chat.system.transform": async (_input, output) => {
|
|
88
61
|
const blocks = await store.listBlocks("all");
|
|
89
|
-
const error = store.getLastError?.() ?? null;
|
|
90
|
-
|
|
91
|
-
// If we got blocks, show them. Otherwise, just show the error warning.
|
|
92
62
|
const xml = renderMemoryBlocks(blocks);
|
|
93
|
-
const errorWarning = getSystemErrorWarning(error);
|
|
94
|
-
|
|
95
|
-
if (!xml && errorWarning) {
|
|
96
|
-
output.system.push(errorWarning);
|
|
97
|
-
return;
|
|
98
|
-
}
|
|
99
|
-
|
|
100
63
|
if (!xml) return;
|
|
101
64
|
|
|
102
65
|
// Insert early (right after provider header) for salience.
|
|
@@ -104,11 +67,6 @@ export const MemoryPlugin: Plugin = async (input) => {
|
|
|
104
67
|
const insertAt = output.system.length > 0 ? 1 : 0;
|
|
105
68
|
output.system.splice(insertAt, 0, xml);
|
|
106
69
|
|
|
107
|
-
// Append error warning if there was an error loading memories
|
|
108
|
-
if (errorWarning) {
|
|
109
|
-
output.system.push(errorWarning);
|
|
110
|
-
}
|
|
111
|
-
|
|
112
70
|
// Append journal instructions at the end (preserves memory block cache)
|
|
113
71
|
if (journalSystemNote) {
|
|
114
72
|
output.system.push(journalSystemNote);
|