myagentmemory 0.4.15 → 0.4.17
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/LICENSE +1 -0
- package/README.md +17 -4
- package/dist/cli-spec.d.ts +1 -1
- package/dist/cli-spec.js +14 -2
- package/dist/cli.js +107 -42
- package/dist/plugin-bootstrap.js +2 -2
- package/dist/plugin-host.d.ts +18 -0
- package/dist/plugin-runtime.d.ts +8 -1
- package/dist/plugin-runtime.js +39 -0
- package/dist/plugin-service.js +129 -42
- package/docs/official-plugin-bootstrap.md +29 -21
- package/package.json +1 -1
- package/src/cli-spec.ts +14 -2
- package/src/cli.ts +112 -51
- package/src/plugin-bootstrap.ts +2 -2
- package/src/plugin-host.ts +20 -0
- package/src/plugin-runtime.ts +64 -0
- package/src/plugin-service.ts +133 -43
package/src/cli.ts
CHANGED
|
@@ -25,6 +25,7 @@
|
|
|
25
25
|
import { spawn } from "node:child_process";
|
|
26
26
|
import * as fs from "node:fs";
|
|
27
27
|
|
|
28
|
+
import { COMMAND_DESCRIPTIONS, COMMANDS } from "./cli-spec.js";
|
|
28
29
|
import { type CompletionShell, detectCompletionShell, generateCompletion, installCompletion } from "./completions.js";
|
|
29
30
|
|
|
30
31
|
import {
|
|
@@ -73,6 +74,7 @@ import {
|
|
|
73
74
|
PluginBootstrapFailure,
|
|
74
75
|
type PluginBootstrapResultV1,
|
|
75
76
|
} from "./plugin-bootstrap.js";
|
|
77
|
+
import type { PluginContextSectionV1 } from "./plugin-host.js";
|
|
76
78
|
import { InstalledPluginRuntimeV1 } from "./plugin-runtime.js";
|
|
77
79
|
|
|
78
80
|
declare const __VERSION__: string;
|
|
@@ -186,21 +188,23 @@ function openExternalUrl(url: string): boolean {
|
|
|
186
188
|
|
|
187
189
|
function printProOverview(installed: boolean): void {
|
|
188
190
|
console.log("");
|
|
189
|
-
console.log("
|
|
190
|
-
console.log(" Session Intelligence Recall decisions and context across Pi, Codex, and Claude Code sessions.");
|
|
191
|
-
console.log(" Guided Learning Turn repeated corrections into reviewable, reversible memory.");
|
|
192
|
-
console.log(" Local Web Console Inspect memories, activity, health, and settings in your browser.");
|
|
191
|
+
console.log("Core remembers what you save. Pro learns from what you do.");
|
|
193
192
|
console.log("");
|
|
194
|
-
console.log("
|
|
193
|
+
console.log("AgentMemory Pro:");
|
|
194
|
+
console.log(" Recall coding history Find decisions and context across Pi, Codex, and Claude Code sessions.");
|
|
195
|
+
console.log(" Learn from corrections Turn repeated fixes into reviewable, reversible memory.");
|
|
196
|
+
console.log(" See and control learning Inspect what AgentMemory remembers and why in the Memory Dashboard.");
|
|
197
|
+
console.log("");
|
|
198
|
+
console.log("No account is required for the free preview. Your coding history stays on this device.");
|
|
195
199
|
console.log("");
|
|
196
200
|
if (installed) {
|
|
197
201
|
console.log("Try it:");
|
|
198
202
|
console.log(' agent-memory recall "what did we decide about authentication?"');
|
|
199
203
|
console.log(" agent-memory learn");
|
|
200
|
-
console.log(" agent-memory
|
|
204
|
+
console.log(" agent-memory dashboard");
|
|
201
205
|
} else {
|
|
202
|
-
console.log("Start your Pro
|
|
203
|
-
console.log(" agent-memory
|
|
206
|
+
console.log("Start your free Pro preview:");
|
|
207
|
+
console.log(" agent-memory pro install");
|
|
204
208
|
}
|
|
205
209
|
}
|
|
206
210
|
|
|
@@ -241,12 +245,10 @@ function printPluginResult(result: PluginBootstrapResultV1, json: boolean, allow
|
|
|
241
245
|
break;
|
|
242
246
|
case "not_installed":
|
|
243
247
|
console.log("AgentMemory Pro is not installed.");
|
|
244
|
-
console.log("Run: agent-memory
|
|
248
|
+
console.log("Run: agent-memory pro install");
|
|
245
249
|
break;
|
|
246
250
|
case "auth_required":
|
|
247
|
-
console.log(
|
|
248
|
-
"Run this command in an interactive terminal to enter an email and activate free daily access.",
|
|
249
|
-
);
|
|
251
|
+
console.log("Run agent-memory pro install to activate the free preview.");
|
|
250
252
|
break;
|
|
251
253
|
case "renewal_required":
|
|
252
254
|
console.log("Renew AgentMemory Pro to continue using paid capabilities.");
|
|
@@ -280,10 +282,23 @@ async function cmdContext(flags: Record<string, string | boolean>) {
|
|
|
280
282
|
ensureDirs();
|
|
281
283
|
if (!noSearch && query) await ensureQmdAvailableForSync();
|
|
282
284
|
const searchResults = noSearch ? "" : await searchRelevantMemories(query);
|
|
283
|
-
const
|
|
285
|
+
const coreContext = buildMemoryContext(searchResults);
|
|
286
|
+
let pluginSections: PluginContextSectionV1[] = [];
|
|
287
|
+
try {
|
|
288
|
+
pluginSections = await new InstalledPluginRuntimeV1({ coreVersion: VERSION }).provideContext({
|
|
289
|
+
host: "agent-memory-cli",
|
|
290
|
+
cwd: process.cwd(),
|
|
291
|
+
query: query || undefined,
|
|
292
|
+
signal: new AbortController().signal,
|
|
293
|
+
});
|
|
294
|
+
} catch {
|
|
295
|
+
// Optional Pro context must never make public-core context unavailable.
|
|
296
|
+
}
|
|
297
|
+
const pluginContext = pluginSections.map((section) => `${section.label}\n\n${section.content}`).join("\n\n");
|
|
298
|
+
const context = [coreContext, pluginContext].filter(Boolean).join("\n\n");
|
|
284
299
|
|
|
285
300
|
if (json) {
|
|
286
|
-
output({ context, directory: getMemoryDir() }, true);
|
|
301
|
+
output({ context, directory: getMemoryDir(), ...(pluginSections.length ? { pluginSections } : {}) }, true);
|
|
287
302
|
} else {
|
|
288
303
|
if (context) {
|
|
289
304
|
process.stdout.write(context);
|
|
@@ -811,8 +826,8 @@ async function cmdInit(flags: Record<string, string | boolean>) {
|
|
|
811
826
|
const plugin = await createDefaultPluginBootstrap(VERSION).list();
|
|
812
827
|
if (plugin.result === "not_installed") {
|
|
813
828
|
console.log("");
|
|
814
|
-
console.log("Optional:
|
|
815
|
-
console.log("
|
|
829
|
+
console.log("Optional: Pro recalls coding history and learns from repeated corrections.");
|
|
830
|
+
console.log("Try it without an account: agent-memory pro install");
|
|
816
831
|
}
|
|
817
832
|
} catch {
|
|
818
833
|
// Commercial discovery must never make core initialization fail.
|
|
@@ -957,8 +972,8 @@ async function cmdStatus(flags: Record<string, string | boolean>) {
|
|
|
957
972
|
}
|
|
958
973
|
if (!officialPlugin.installed) {
|
|
959
974
|
console.log("");
|
|
960
|
-
console.log("
|
|
961
|
-
console.log("
|
|
975
|
+
console.log("AgentMemory Pro: not installed");
|
|
976
|
+
console.log(" try without an account: agent-memory pro install");
|
|
962
977
|
}
|
|
963
978
|
}
|
|
964
979
|
}
|
|
@@ -1001,9 +1016,10 @@ Usage:
|
|
|
1001
1016
|
agent-memory plugin uninstall --yes
|
|
1002
1017
|
agent-memory plugin manage [--no-browser]
|
|
1003
1018
|
|
|
1004
|
-
The public core remains fully usable without AgentMemory Pro.
|
|
1005
|
-
|
|
1006
|
-
|
|
1019
|
+
The public core remains fully usable without AgentMemory Pro. Install uses a random
|
|
1020
|
+
installation identifier and requires no account or email. The free preview includes
|
|
1021
|
+
10 recalls and one learning scan per local day; indexing and the Memory Dashboard
|
|
1022
|
+
remain available. Memory and session content stay on this device.`);
|
|
1007
1023
|
}
|
|
1008
1024
|
|
|
1009
1025
|
function pluginCommandFailure(command: string, error: unknown): PluginBootstrapResultV1 {
|
|
@@ -1028,24 +1044,24 @@ function pluginCommandFailure(command: string, error: unknown): PluginBootstrapR
|
|
|
1028
1044
|
};
|
|
1029
1045
|
}
|
|
1030
1046
|
|
|
1031
|
-
async function cmdPlugin(
|
|
1047
|
+
async function cmdPlugin(
|
|
1048
|
+
flags: Record<string, string | boolean>,
|
|
1049
|
+
positional: string[],
|
|
1050
|
+
): Promise<PluginBootstrapResultV1 | null> {
|
|
1032
1051
|
const json = hasFlag(flags, "json");
|
|
1033
1052
|
const subcommand = positional[0] ?? "list";
|
|
1034
1053
|
if (subcommand === "help" || hasFlag(flags, "help")) {
|
|
1035
1054
|
printPluginUsage();
|
|
1036
|
-
return;
|
|
1055
|
+
return null;
|
|
1037
1056
|
}
|
|
1038
1057
|
const channel = getFlag(flags, "channel") ?? "stable";
|
|
1039
1058
|
if (channel !== "stable") {
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
new PluginBootstrapFailure("channel_invalid", "--channel supports only 'stable'"),
|
|
1044
|
-
),
|
|
1045
|
-
json,
|
|
1046
|
-
false,
|
|
1059
|
+
const failure = pluginCommandFailure(
|
|
1060
|
+
subcommand,
|
|
1061
|
+
new PluginBootstrapFailure("channel_invalid", "--channel supports only 'stable'"),
|
|
1047
1062
|
);
|
|
1048
|
-
|
|
1063
|
+
printPluginResult(failure, json, false);
|
|
1064
|
+
return failure;
|
|
1049
1065
|
}
|
|
1050
1066
|
const allowBrowser = !json && !hasFlag(flags, "no-browser") && Boolean(process.stdin.isTTY && process.stdout.isTTY);
|
|
1051
1067
|
const manager = createDefaultPluginBootstrap(VERSION);
|
|
@@ -1098,6 +1114,55 @@ async function cmdPlugin(flags: Record<string, string | boolean>, positional: st
|
|
|
1098
1114
|
result = pluginCommandFailure(subcommand, error);
|
|
1099
1115
|
}
|
|
1100
1116
|
printPluginResult(result, json, allowBrowser && (subcommand === "install" || subcommand === "manage"));
|
|
1117
|
+
return result;
|
|
1118
|
+
}
|
|
1119
|
+
|
|
1120
|
+
async function printFirstRunProof(): Promise<void> {
|
|
1121
|
+
try {
|
|
1122
|
+
const result = await new InstalledPluginRuntimeV1({ coreVersion: VERSION }).run("index", {
|
|
1123
|
+
args: [],
|
|
1124
|
+
flags: {},
|
|
1125
|
+
signal: new AbortController().signal,
|
|
1126
|
+
});
|
|
1127
|
+
if (!result?.ok || !result.data || typeof result.data !== "object") return;
|
|
1128
|
+
const stats = (result.data as { stats?: { discovered?: Record<string, number>; selected?: number } }).stats;
|
|
1129
|
+
if (!stats?.discovered) return;
|
|
1130
|
+
const hosts = [
|
|
1131
|
+
["Claude Code", stats.discovered.claude ?? 0],
|
|
1132
|
+
["Codex", stats.discovered.codex ?? 0],
|
|
1133
|
+
["Pi", stats.discovered.pi ?? 0],
|
|
1134
|
+
] as const;
|
|
1135
|
+
console.log("");
|
|
1136
|
+
console.log("Found local coding history:");
|
|
1137
|
+
for (const [label, count] of hosts) console.log(` ${label.padEnd(13)} ${count} sessions`);
|
|
1138
|
+
console.log("");
|
|
1139
|
+
console.log(`${stats.selected ?? 0} sessions available for local recall. Nothing was uploaded.`);
|
|
1140
|
+
console.log("");
|
|
1141
|
+
console.log('Try: agent-memory recall "what did we decide about authentication?"');
|
|
1142
|
+
console.log("Open: agent-memory dashboard");
|
|
1143
|
+
} catch {
|
|
1144
|
+
// Personalized proof is helpful but must never turn a successful install into a failure.
|
|
1145
|
+
}
|
|
1146
|
+
}
|
|
1147
|
+
|
|
1148
|
+
async function cmdPro(flags: Record<string, string | boolean>, positional: string[]): Promise<void> {
|
|
1149
|
+
const subcommand = positional[0];
|
|
1150
|
+
if (!subcommand) {
|
|
1151
|
+
await cmdPlugin(flags, ["list"]);
|
|
1152
|
+
return;
|
|
1153
|
+
}
|
|
1154
|
+
const mapped = subcommand === "upgrade" ? "update" : subcommand;
|
|
1155
|
+
if (!["install", "status", "update", "manage"].includes(mapped)) {
|
|
1156
|
+
const json = hasFlag(flags, "json");
|
|
1157
|
+
const message = `Unknown Pro command: ${subcommand}. Available commands: install, status, upgrade, manage.`;
|
|
1158
|
+
if (json) console.log(JSON.stringify({ error: message }));
|
|
1159
|
+
else console.error(`Error: ${message}`);
|
|
1160
|
+
process.exitCode = 1;
|
|
1161
|
+
return;
|
|
1162
|
+
}
|
|
1163
|
+
const result = await cmdPlugin(flags, [mapped]);
|
|
1164
|
+
if (!hasFlag(flags, "json") && mapped === "install" && ["installed", "upgraded"].includes(result?.result ?? ""))
|
|
1165
|
+
await printFirstRunProof();
|
|
1101
1166
|
}
|
|
1102
1167
|
|
|
1103
1168
|
// ---------------------------------------------------------------------------
|
|
@@ -1105,28 +1170,18 @@ async function cmdPlugin(flags: Record<string, string | boolean>, positional: st
|
|
|
1105
1170
|
// ---------------------------------------------------------------------------
|
|
1106
1171
|
|
|
1107
1172
|
function printUsage() {
|
|
1173
|
+
const commandWidth = Math.max(...COMMANDS.map((command) => command.length));
|
|
1174
|
+
const commandList = COMMANDS.map(
|
|
1175
|
+
(command) => ` ${command.padEnd(commandWidth)} ${COMMAND_DESCRIPTIONS[command]}`,
|
|
1176
|
+
).join("\n");
|
|
1177
|
+
|
|
1108
1178
|
console.log(`agent-memory — persistent memory for coding agents
|
|
1109
1179
|
|
|
1110
1180
|
Usage:
|
|
1111
1181
|
agent-memory <command> [options]
|
|
1112
1182
|
|
|
1113
1183
|
Commands:
|
|
1114
|
-
|
|
1115
|
-
install-skills Install (or --uninstall) bundled skills
|
|
1116
|
-
uninstall-skills Uninstall bundled skills
|
|
1117
|
-
context Build context; optionally retrieve memories with --query
|
|
1118
|
-
write Write to memory files (default: daily; optional --source-uri)
|
|
1119
|
-
read Read memory files
|
|
1120
|
-
scratchpad Manage checklist items
|
|
1121
|
-
search Search across memory files (requires qmd)
|
|
1122
|
-
distil Generate compact MEMORY.md index from daily logs + topics
|
|
1123
|
-
sync Re-index and embed all files (requires qmd)
|
|
1124
|
-
init Initialize memory directory and qmd collection
|
|
1125
|
-
status Show configuration and status (--probe for a live embeddings check)
|
|
1126
|
-
completion Install or print shell completion
|
|
1127
|
-
install-hooks Install managed SessionStart hooks
|
|
1128
|
-
uninstall-hooks Remove only managed SessionStart hooks
|
|
1129
|
-
plugin Discover, install, update, or remove optional official plugins
|
|
1184
|
+
${commandList}
|
|
1130
1185
|
|
|
1131
1186
|
Global flags:
|
|
1132
1187
|
--dir <path> Override memory directory
|
|
@@ -1152,8 +1207,10 @@ Examples:
|
|
|
1152
1207
|
agent-memory status --json
|
|
1153
1208
|
agent-memory completion zsh
|
|
1154
1209
|
agent-memory install-hooks --yes
|
|
1155
|
-
agent-memory
|
|
1156
|
-
agent-memory
|
|
1210
|
+
agent-memory pro status
|
|
1211
|
+
agent-memory pro install
|
|
1212
|
+
agent-memory recall "what did we decide about authentication?"
|
|
1213
|
+
agent-memory dashboard`);
|
|
1157
1214
|
}
|
|
1158
1215
|
|
|
1159
1216
|
// ---------------------------------------------------------------------------
|
|
@@ -1245,18 +1302,22 @@ async function main() {
|
|
|
1245
1302
|
case "plugin":
|
|
1246
1303
|
await cmdPlugin(flags, positional);
|
|
1247
1304
|
break;
|
|
1305
|
+
case "pro":
|
|
1306
|
+
await cmdPro(flags, positional);
|
|
1307
|
+
break;
|
|
1248
1308
|
default: {
|
|
1249
1309
|
const controller = new AbortController();
|
|
1250
1310
|
const abort = () => controller.abort();
|
|
1251
1311
|
process.once("SIGINT", abort);
|
|
1252
1312
|
try {
|
|
1253
|
-
const
|
|
1313
|
+
const pluginCommand = command === "dashboard" ? "web" : command;
|
|
1314
|
+
const result = await new InstalledPluginRuntimeV1({ coreVersion: VERSION }).run(pluginCommand, {
|
|
1254
1315
|
args: positional,
|
|
1255
1316
|
flags,
|
|
1256
1317
|
signal: controller.signal,
|
|
1257
1318
|
});
|
|
1258
1319
|
if (!result) exitError(`Unknown command: ${command}. Run 'agent-memory help' for usage.`, json);
|
|
1259
|
-
if (!result.ok) exitError(result.error?.message ?? `Plugin command ${
|
|
1320
|
+
if (!result.ok) exitError(result.error?.message ?? `Plugin command ${pluginCommand} failed`, json);
|
|
1260
1321
|
output(result.data ?? { ok: true }, json);
|
|
1261
1322
|
} finally {
|
|
1262
1323
|
process.removeListener("SIGINT", abort);
|
package/src/plugin-bootstrap.ts
CHANGED
|
@@ -195,8 +195,8 @@ const MISSING_ENTITLEMENT: PluginEntitlementStatusV1 = {
|
|
|
195
195
|
};
|
|
196
196
|
|
|
197
197
|
const OFFICIAL_PLUGINS = [
|
|
198
|
-
{ id: OFFICIAL_PLUGIN_IDS[0], name: "
|
|
199
|
-
{ id: OFFICIAL_PLUGIN_IDS[1], name: "
|
|
198
|
+
{ id: OFFICIAL_PLUGIN_IDS[0], name: "Coding History Recall" },
|
|
199
|
+
{ id: OFFICIAL_PLUGIN_IDS[1], name: "Memory Dashboard" },
|
|
200
200
|
] as const;
|
|
201
201
|
|
|
202
202
|
const PACKAGE_MAX_BYTES = 64 * 1024 * 1024;
|
package/src/plugin-host.ts
CHANGED
|
@@ -131,11 +131,31 @@ export interface PluginStructuredErrorV1 {
|
|
|
131
131
|
retryable?: boolean;
|
|
132
132
|
}
|
|
133
133
|
|
|
134
|
+
export interface PluginContextSectionV1 {
|
|
135
|
+
id: string;
|
|
136
|
+
label: string;
|
|
137
|
+
content: string;
|
|
138
|
+
artifactPath?: string;
|
|
139
|
+
metadata?: Record<string, unknown>;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
export interface PluginContextProviderV1 {
|
|
143
|
+
name: string;
|
|
144
|
+
requiredCapability: string;
|
|
145
|
+
provide(context: {
|
|
146
|
+
host: string;
|
|
147
|
+
cwd?: string;
|
|
148
|
+
query?: string;
|
|
149
|
+
signal: AbortSignal;
|
|
150
|
+
}): Promise<PluginContextSectionV1[]>;
|
|
151
|
+
}
|
|
152
|
+
|
|
134
153
|
export interface AgentMemoryPluginHostV1 {
|
|
135
154
|
apiVersion: 1;
|
|
136
155
|
coreVersion: string;
|
|
137
156
|
registerCommand(command: PluginCommandV1): void;
|
|
138
157
|
registerSessionStartHook(hook: PluginSessionStartHookV1): void;
|
|
158
|
+
registerContextProvider?(provider: PluginContextProviderV1): void;
|
|
139
159
|
getStateDirectory(): string;
|
|
140
160
|
getMemoryDirectory(): string;
|
|
141
161
|
getEntitlement(): Promise<PluginEntitlementStatusV1>;
|
package/src/plugin-runtime.ts
CHANGED
|
@@ -23,6 +23,8 @@ import {
|
|
|
23
23
|
type PluginCommandContextV1,
|
|
24
24
|
type PluginCommandResultV1,
|
|
25
25
|
type PluginCommandV1,
|
|
26
|
+
type PluginContextProviderV1,
|
|
27
|
+
type PluginContextSectionV1,
|
|
26
28
|
type PluginEntitlementStatusV1,
|
|
27
29
|
type PluginMemoryCorrectionV1,
|
|
28
30
|
type PluginMemoryWriteV1,
|
|
@@ -38,6 +40,11 @@ interface RegisteredCommand {
|
|
|
38
40
|
pluginId: string;
|
|
39
41
|
}
|
|
40
42
|
|
|
43
|
+
interface RegisteredContextProvider {
|
|
44
|
+
provider: PluginContextProviderV1;
|
|
45
|
+
pluginId: string;
|
|
46
|
+
}
|
|
47
|
+
|
|
41
48
|
export interface PluginRuntimeOptionsV1 {
|
|
42
49
|
coreVersion: string;
|
|
43
50
|
store?: PluginInstallStoreV1;
|
|
@@ -130,6 +137,7 @@ export class InstalledPluginRuntimeV1 {
|
|
|
130
137
|
private readonly backend: PluginBootstrapBackendV1;
|
|
131
138
|
private readonly commands = new Map<string, RegisteredCommand>();
|
|
132
139
|
private readonly hooks: PluginSessionStartHookV1[] = [];
|
|
140
|
+
private readonly contextProviders: RegisteredContextProvider[] = [];
|
|
133
141
|
private loaded = false;
|
|
134
142
|
|
|
135
143
|
constructor(private readonly options: PluginRuntimeOptionsV1) {
|
|
@@ -202,6 +210,49 @@ export class InstalledPluginRuntimeV1 {
|
|
|
202
210
|
}
|
|
203
211
|
}
|
|
204
212
|
|
|
213
|
+
async provideContext(context: {
|
|
214
|
+
host: string;
|
|
215
|
+
cwd?: string;
|
|
216
|
+
query?: string;
|
|
217
|
+
signal: AbortSignal;
|
|
218
|
+
}): Promise<PluginContextSectionV1[]> {
|
|
219
|
+
if (!(await this.load()) || this.contextProviders.length === 0) return [];
|
|
220
|
+
const entitlement = await this.refreshEntitlement();
|
|
221
|
+
const sections: PluginContextSectionV1[] = [];
|
|
222
|
+
for (const registered of this.contextProviders) {
|
|
223
|
+
if (!isPluginCapabilityEnabled(entitlement, registered.provider.requiredCapability)) continue;
|
|
224
|
+
const provided = await registered.provider.provide(context);
|
|
225
|
+
if (!Array.isArray(provided) || provided.length > 16)
|
|
226
|
+
throw new PluginBootstrapFailure(
|
|
227
|
+
"plugin_context_invalid",
|
|
228
|
+
`Plugin ${registered.pluginId} returned invalid context sections`,
|
|
229
|
+
);
|
|
230
|
+
for (const section of provided) {
|
|
231
|
+
if (
|
|
232
|
+
!section ||
|
|
233
|
+
typeof section.id !== "string" ||
|
|
234
|
+
section.id.length === 0 ||
|
|
235
|
+
section.id.length > 256 ||
|
|
236
|
+
typeof section.label !== "string" ||
|
|
237
|
+
section.label.length === 0 ||
|
|
238
|
+
section.label.length > 256 ||
|
|
239
|
+
typeof section.content !== "string" ||
|
|
240
|
+
Buffer.byteLength(section.content, "utf-8") > 64 * 1024 ||
|
|
241
|
+
(section.artifactPath !== undefined &&
|
|
242
|
+
(typeof section.artifactPath !== "string" || section.artifactPath.length > 4_096)) ||
|
|
243
|
+
(section.metadata !== undefined &&
|
|
244
|
+
(!section.metadata || typeof section.metadata !== "object" || Array.isArray(section.metadata)))
|
|
245
|
+
)
|
|
246
|
+
throw new PluginBootstrapFailure(
|
|
247
|
+
"plugin_context_invalid",
|
|
248
|
+
`Plugin ${registered.pluginId} returned an invalid context section`,
|
|
249
|
+
);
|
|
250
|
+
sections.push(structuredClone(section));
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
return sections;
|
|
254
|
+
}
|
|
255
|
+
|
|
205
256
|
private createHost(manifest: AgentMemoryPluginManifestV1): AgentMemoryPluginHostV1 {
|
|
206
257
|
const descriptors = new Map(manifest.commands.map((command) => [command.name, command]));
|
|
207
258
|
const stateRoot = path.join(this.store.root, "state");
|
|
@@ -242,6 +293,19 @@ export class InstalledPluginRuntimeV1 {
|
|
|
242
293
|
);
|
|
243
294
|
this.hooks.push(hook);
|
|
244
295
|
},
|
|
296
|
+
registerContextProvider: (provider) => {
|
|
297
|
+
if (!(manifest.capabilities ?? []).includes(provider.requiredCapability))
|
|
298
|
+
throw new PluginBootstrapFailure(
|
|
299
|
+
"plugin_context_invalid",
|
|
300
|
+
`Plugin ${manifest.id} registered a context provider with an undeclared capability`,
|
|
301
|
+
);
|
|
302
|
+
if (!provider.name || this.contextProviders.some((item) => item.provider.name === provider.name))
|
|
303
|
+
throw new PluginBootstrapFailure(
|
|
304
|
+
"plugin_context_invalid",
|
|
305
|
+
`Plugin context provider ${provider.name || "(unnamed)"} is invalid or already registered`,
|
|
306
|
+
);
|
|
307
|
+
this.contextProviders.push({ provider, pluginId: manifest.id });
|
|
308
|
+
},
|
|
245
309
|
getStateDirectory: () => stateDirectory,
|
|
246
310
|
getMemoryDirectory: () => {
|
|
247
311
|
assertPermission(manifest, "memory:read");
|