@ai-agent-forge/plugin-sdk 0.88.1 → 0.88.3

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.
@@ -1 +1 @@
1
- {"version":3,"file":"capability-manifest.d.ts","sourceRoot":"","sources":["../src/capability-manifest.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,KAAK,EAKX,cAAc,EACd,MAAM,iBAAiB,CAAC;AA+IzB,6EAA6E;AAC7E,wBAAgB,6BAA6B,CAAC,KAAK,EAAE,OAAO,EAAE,YAAY,SAAe,GAAG,cAAc,CA8DzG","sourcesContent":["/**\n * Capability plugin manifest schema (plugin.json) and its pure validation.\n *\n * Authority: `@agent-forge/plugin-sdk` (D-075 S2). The host re-exports these\n * symbols from its loader module; filesystem discovery, jiti loading, and\n * lifecycle dispatch stay host-side.\n */\n\nimport { validRange } from \"semver\";\nimport type {\n\tAgentDefinitionDeclaration,\n\tPluginAgentRole,\n\tPluginCapabilityDeclaration,\n\tPluginCapabilityRequirement,\n\tPluginManifest,\n} from \"./public-api.ts\";\nimport { EXPERIMENTAL_PUBLIC_API_VERSION } from \"./public-api.ts\";\n\nfunction isStringArray(value: unknown): value is string[] {\n\treturn Array.isArray(value) && value.every((entry) => typeof entry === \"string\");\n}\n\nfunction isObject(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction isJsonConfigValue(value: unknown): boolean {\n\tif (value === null || typeof value === \"boolean\" || typeof value === \"string\") return true;\n\tif (typeof value === \"number\") return Number.isFinite(value);\n\tif (Array.isArray(value)) return value.every(isJsonConfigValue);\n\tif (!isObject(value)) return false;\n\treturn Object.values(value).every(isJsonConfigValue);\n}\n\nfunction assertPluginCapabilityId(value: unknown, field: string, manifestPath: string): asserts value is string {\n\tif (typeof value !== \"string\" || !value.trim()) {\n\t\tthrow new Error(`Capability plugin ${field} must be a non-empty string: ${manifestPath}`);\n\t}\n}\n\nfunction assertPluginCapabilityVersion(value: unknown, field: string, manifestPath: string): asserts value is number {\n\tif (typeof value !== \"number\" || !Number.isSafeInteger(value) || value < 1) {\n\t\tthrow new Error(`Capability plugin ${field} must be a positive safe integer: ${manifestPath}`);\n\t}\n}\n\nfunction capabilityKey(id: string, version: number): string {\n\treturn `${id}\\u0000${version}`;\n}\n\nfunction parsePluginAgentRoles(value: unknown, manifestPath: string): readonly PluginAgentRole[] | undefined {\n\tif (value === undefined) return undefined;\n\tif (!Array.isArray(value)) throw new Error(`Capability plugin roles must be an array: ${manifestPath}`);\n\tconst roles: PluginAgentRole[] = [];\n\tconst seen = new Set<string>();\n\tfor (const [index, role] of value.entries()) {\n\t\tif (role !== \"root-agent-controller\" && role !== \"child-agent-controller\") {\n\t\t\tthrow new Error(`Capability plugin roles[${index}] is invalid: ${manifestPath}`);\n\t\t}\n\t\tif (seen.has(role)) throw new Error(`Capability plugin roles duplicates ${role}: ${manifestPath}`);\n\t\tseen.add(role);\n\t\troles.push(role);\n\t}\n\treturn roles;\n}\n\nfunction parsePluginAgentDeclarations(\n\tvalue: unknown,\n\troles: readonly PluginAgentRole[] | undefined,\n\tmanifestPath: string,\n): readonly AgentDefinitionDeclaration[] | undefined {\n\tif (value === undefined) return undefined;\n\tif (!Array.isArray(value)) throw new Error(`Capability plugin agents must be an array: ${manifestPath}`);\n\tconst declarations: AgentDefinitionDeclaration[] = [];\n\tconst seen = new Set<string>();\n\tfor (const [index, candidate] of value.entries()) {\n\t\tif (!isObject(candidate))\n\t\t\tthrow new Error(`Capability plugin agents[${index}] must be an object: ${manifestPath}`);\n\t\tconst { id, version, role, entry } = candidate;\n\t\tassertPluginCapabilityId(id, `agents[${index}].id`, manifestPath);\n\t\tassertPluginCapabilityVersion(version, `agents[${index}].version`, manifestPath);\n\t\tif (role !== \"root-agent-controller\" && role !== \"child-agent-controller\") {\n\t\t\tthrow new Error(`Capability plugin agents[${index}].role is invalid: ${manifestPath}`);\n\t\t}\n\t\tif (typeof entry !== \"string\" || !entry.trim()) {\n\t\t\tthrow new Error(`Capability plugin agents[${index}].entry must be a non-empty string: ${manifestPath}`);\n\t\t}\n\t\tif (roles !== undefined && !roles.includes(role)) {\n\t\t\tthrow new Error(`Capability plugin agents[${index}].role is not declared in roles: ${manifestPath}`);\n\t\t}\n\t\tconst key = capabilityKey(id, version);\n\t\tif (seen.has(key)) throw new Error(`Capability plugin agents duplicates ${id}@${version}: ${manifestPath}`);\n\t\tseen.add(key);\n\t\tdeclarations.push({ id, version, role, entry });\n\t}\n\treturn declarations;\n}\n\nfunction parsePluginCapabilityDeclarations(\n\tvalue: unknown,\n\tmanifestPath: string,\n): readonly PluginCapabilityDeclaration[] | undefined {\n\tif (value === undefined) return undefined;\n\tif (!Array.isArray(value)) {\n\t\tthrow new Error(`Capability plugin provides must be an array: ${manifestPath}`);\n\t}\n\tconst declarations: PluginCapabilityDeclaration[] = [];\n\tconst seen = new Set<string>();\n\tfor (const [index, candidate] of value.entries()) {\n\t\tif (!isObject(candidate)) {\n\t\t\tthrow new Error(`Capability plugin provides[${index}] must be an object: ${manifestPath}`);\n\t\t}\n\t\tconst { id, version, kind } = candidate;\n\t\tassertPluginCapabilityId(id, `provides[${index}].id`, manifestPath);\n\t\tassertPluginCapabilityVersion(version, `provides[${index}].version`, manifestPath);\n\t\tif (kind !== \"service\" && kind !== \"contribution\" && kind !== \"transform\") {\n\t\t\tthrow new Error(`Capability plugin provides[${index}].kind is invalid: ${manifestPath}`);\n\t\t}\n\t\tconst key = capabilityKey(id, version);\n\t\tif (seen.has(key)) {\n\t\t\tthrow new Error(`Capability plugin provides duplicates ${id}@${version}: ${manifestPath}`);\n\t\t}\n\t\tseen.add(key);\n\t\tdeclarations.push({ id, version, kind });\n\t}\n\treturn declarations;\n}\n\nfunction parsePluginCapabilityRequirements(\n\tvalue: unknown,\n\tmanifestPath: string,\n): readonly PluginCapabilityRequirement[] | undefined {\n\tif (value === undefined) return undefined;\n\tif (!Array.isArray(value)) {\n\t\tthrow new Error(`Capability plugin requires must be an array: ${manifestPath}`);\n\t}\n\tconst requirements: PluginCapabilityRequirement[] = [];\n\tconst seen = new Set<string>();\n\tfor (const [index, candidate] of value.entries()) {\n\t\tif (!isObject(candidate)) {\n\t\t\tthrow new Error(`Capability plugin requires[${index}] must be an object: ${manifestPath}`);\n\t\t}\n\t\tconst { id, version, optional } = candidate;\n\t\tassertPluginCapabilityId(id, `requires[${index}].id`, manifestPath);\n\t\tassertPluginCapabilityVersion(version, `requires[${index}].version`, manifestPath);\n\t\tif (optional !== undefined && typeof optional !== \"boolean\") {\n\t\t\tthrow new Error(`Capability plugin requires[${index}].optional must be a boolean: ${manifestPath}`);\n\t\t}\n\t\tconst key = capabilityKey(id, version);\n\t\tif (seen.has(key)) {\n\t\t\tthrow new Error(`Capability plugin requires duplicates ${id}@${version}: ${manifestPath}`);\n\t\t}\n\t\tseen.add(key);\n\t\trequirements.push(optional === undefined ? { id, version } : { id, version, optional });\n\t}\n\treturn requirements;\n}\n\n/** Parse a capability plugin manifest without accepting malformed fields. */\nexport function parseCapabilityPluginManifest(value: unknown, manifestPath = \"<manifest>\"): PluginManifest {\n\tif (!isObject(value)) throw new Error(`Capability plugin manifest must be an object: ${manifestPath}`);\n\tconst {\n\t\tid,\n\t\tversion,\n\t\thostVersion,\n\t\tapiVersion,\n\t\tentry,\n\t\trequiredCapabilities,\n\t\toptionalCapabilities,\n\t\tprovides,\n\t\trequires,\n\t\troles,\n\t\tagents,\n\t\tconfig,\n\t} = value;\n\tif (\n\t\ttypeof id !== \"string\" ||\n\t\ttypeof version !== \"string\" ||\n\t\ttypeof apiVersion !== \"string\" ||\n\t\ttypeof entry !== \"string\"\n\t) {\n\t\tthrow new Error(`Capability plugin manifest requires string id, version, apiVersion, and entry: ${manifestPath}`);\n\t}\n\tif (apiVersion !== EXPERIMENTAL_PUBLIC_API_VERSION) {\n\t\tthrow new Error(`Unsupported plugin API version: ${apiVersion}: ${manifestPath}`);\n\t}\n\tif (\n\t\thostVersion !== undefined &&\n\t\t(typeof hostVersion !== \"string\" || hostVersion.trim() === \"\" || validRange(hostVersion) === null)\n\t) {\n\t\tthrow new Error(\n\t\t\t`Capability plugin hostVersion must be a non-empty string containing a valid semver range (e.g. \">=0.84.0\"): ${manifestPath}`,\n\t\t);\n\t}\n\tif (requiredCapabilities !== undefined && !isStringArray(requiredCapabilities)) {\n\t\tthrow new Error(`Capability plugin requiredCapabilities must be a string array: ${manifestPath}`);\n\t}\n\tif (optionalCapabilities !== undefined && !isStringArray(optionalCapabilities)) {\n\t\tthrow new Error(`Capability plugin optionalCapabilities must be a string array: ${manifestPath}`);\n\t}\n\tif (config !== undefined && (!isObject(config) || !isJsonConfigValue(config))) {\n\t\tthrow new Error(`Capability plugin config must be a JSON object: ${manifestPath}`);\n\t}\n\tconst parsedProvides = parsePluginCapabilityDeclarations(provides, manifestPath);\n\tconst parsedRequires = parsePluginCapabilityRequirements(requires, manifestPath);\n\tconst parsedRoles = parsePluginAgentRoles(roles, manifestPath);\n\tconst parsedAgents = parsePluginAgentDeclarations(agents, parsedRoles, manifestPath);\n\treturn {\n\t\tid,\n\t\tversion,\n\t\tapiVersion: apiVersion as PluginManifest[\"apiVersion\"],\n\t\tentry,\n\t\trequiredCapabilities,\n\t\toptionalCapabilities,\n\t\t...(hostVersion === undefined ? {} : { hostVersion }),\n\t\t...(parsedProvides === undefined ? {} : { provides: parsedProvides }),\n\t\t...(parsedRequires === undefined ? {} : { requires: parsedRequires }),\n\t\t...(parsedRoles === undefined ? {} : { roles: parsedRoles }),\n\t\t...(parsedAgents === undefined ? {} : { agents: parsedAgents }),\n\t\t...(config === undefined ? {} : { config: config as PluginManifest[\"config\"] }),\n\t};\n}\n"]}
1
+ {"version":3,"file":"capability-manifest.d.ts","sourceRoot":"","sources":["../src/capability-manifest.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,KAAK,EAKX,cAAc,EACd,MAAM,iBAAiB,CAAC;AA+IzB,6EAA6E;AAC7E,wBAAgB,6BAA6B,CAAC,KAAK,EAAE,OAAO,EAAE,YAAY,SAAe,GAAG,cAAc,CAkFzG","sourcesContent":["/**\n * Capability plugin manifest schema (plugin.json) and its pure validation.\n *\n * Authority: `@agent-forge/plugin-sdk` (D-075 S2). The host re-exports these\n * symbols from its loader module; filesystem discovery, jiti loading, and\n * lifecycle dispatch stay host-side.\n */\n\nimport { validRange } from \"semver\";\nimport type {\n\tAgentDefinitionDeclaration,\n\tPluginAgentRole,\n\tPluginCapabilityDeclaration,\n\tPluginCapabilityRequirement,\n\tPluginManifest,\n} from \"./public-api.ts\";\nimport { EXPERIMENTAL_PUBLIC_API_VERSION } from \"./public-api.ts\";\n\nfunction isStringArray(value: unknown): value is string[] {\n\treturn Array.isArray(value) && value.every((entry) => typeof entry === \"string\");\n}\n\nfunction isObject(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction isJsonConfigValue(value: unknown): boolean {\n\tif (value === null || typeof value === \"boolean\" || typeof value === \"string\") return true;\n\tif (typeof value === \"number\") return Number.isFinite(value);\n\tif (Array.isArray(value)) return value.every(isJsonConfigValue);\n\tif (!isObject(value)) return false;\n\treturn Object.values(value).every(isJsonConfigValue);\n}\n\nfunction assertPluginCapabilityId(value: unknown, field: string, manifestPath: string): asserts value is string {\n\tif (typeof value !== \"string\" || !value.trim()) {\n\t\tthrow new Error(`Capability plugin ${field} must be a non-empty string: ${manifestPath}`);\n\t}\n}\n\nfunction assertPluginCapabilityVersion(value: unknown, field: string, manifestPath: string): asserts value is number {\n\tif (typeof value !== \"number\" || !Number.isSafeInteger(value) || value < 1) {\n\t\tthrow new Error(`Capability plugin ${field} must be a positive safe integer: ${manifestPath}`);\n\t}\n}\n\nfunction capabilityKey(id: string, version: number): string {\n\treturn `${id}\\u0000${version}`;\n}\n\nfunction parsePluginAgentRoles(value: unknown, manifestPath: string): readonly PluginAgentRole[] | undefined {\n\tif (value === undefined) return undefined;\n\tif (!Array.isArray(value)) throw new Error(`Capability plugin roles must be an array: ${manifestPath}`);\n\tconst roles: PluginAgentRole[] = [];\n\tconst seen = new Set<string>();\n\tfor (const [index, role] of value.entries()) {\n\t\tif (role !== \"root-agent-controller\" && role !== \"child-agent-controller\") {\n\t\t\tthrow new Error(`Capability plugin roles[${index}] is invalid: ${manifestPath}`);\n\t\t}\n\t\tif (seen.has(role)) throw new Error(`Capability plugin roles duplicates ${role}: ${manifestPath}`);\n\t\tseen.add(role);\n\t\troles.push(role);\n\t}\n\treturn roles;\n}\n\nfunction parsePluginAgentDeclarations(\n\tvalue: unknown,\n\troles: readonly PluginAgentRole[] | undefined,\n\tmanifestPath: string,\n): readonly AgentDefinitionDeclaration[] | undefined {\n\tif (value === undefined) return undefined;\n\tif (!Array.isArray(value)) throw new Error(`Capability plugin agents must be an array: ${manifestPath}`);\n\tconst declarations: AgentDefinitionDeclaration[] = [];\n\tconst seen = new Set<string>();\n\tfor (const [index, candidate] of value.entries()) {\n\t\tif (!isObject(candidate))\n\t\t\tthrow new Error(`Capability plugin agents[${index}] must be an object: ${manifestPath}`);\n\t\tconst { id, version, role, entry } = candidate;\n\t\tassertPluginCapabilityId(id, `agents[${index}].id`, manifestPath);\n\t\tassertPluginCapabilityVersion(version, `agents[${index}].version`, manifestPath);\n\t\tif (role !== \"root-agent-controller\" && role !== \"child-agent-controller\") {\n\t\t\tthrow new Error(`Capability plugin agents[${index}].role is invalid: ${manifestPath}`);\n\t\t}\n\t\tif (typeof entry !== \"string\" || !entry.trim()) {\n\t\t\tthrow new Error(`Capability plugin agents[${index}].entry must be a non-empty string: ${manifestPath}`);\n\t\t}\n\t\tif (roles !== undefined && !roles.includes(role)) {\n\t\t\tthrow new Error(`Capability plugin agents[${index}].role is not declared in roles: ${manifestPath}`);\n\t\t}\n\t\tconst key = capabilityKey(id, version);\n\t\tif (seen.has(key)) throw new Error(`Capability plugin agents duplicates ${id}@${version}: ${manifestPath}`);\n\t\tseen.add(key);\n\t\tdeclarations.push({ id, version, role, entry });\n\t}\n\treturn declarations;\n}\n\nfunction parsePluginCapabilityDeclarations(\n\tvalue: unknown,\n\tmanifestPath: string,\n): readonly PluginCapabilityDeclaration[] | undefined {\n\tif (value === undefined) return undefined;\n\tif (!Array.isArray(value)) {\n\t\tthrow new Error(`Capability plugin provides must be an array: ${manifestPath}`);\n\t}\n\tconst declarations: PluginCapabilityDeclaration[] = [];\n\tconst seen = new Set<string>();\n\tfor (const [index, candidate] of value.entries()) {\n\t\tif (!isObject(candidate)) {\n\t\t\tthrow new Error(`Capability plugin provides[${index}] must be an object: ${manifestPath}`);\n\t\t}\n\t\tconst { id, version, kind } = candidate;\n\t\tassertPluginCapabilityId(id, `provides[${index}].id`, manifestPath);\n\t\tassertPluginCapabilityVersion(version, `provides[${index}].version`, manifestPath);\n\t\tif (kind !== \"service\" && kind !== \"contribution\" && kind !== \"transform\") {\n\t\t\tthrow new Error(`Capability plugin provides[${index}].kind is invalid: ${manifestPath}`);\n\t\t}\n\t\tconst key = capabilityKey(id, version);\n\t\tif (seen.has(key)) {\n\t\t\tthrow new Error(`Capability plugin provides duplicates ${id}@${version}: ${manifestPath}`);\n\t\t}\n\t\tseen.add(key);\n\t\tdeclarations.push({ id, version, kind });\n\t}\n\treturn declarations;\n}\n\nfunction parsePluginCapabilityRequirements(\n\tvalue: unknown,\n\tmanifestPath: string,\n): readonly PluginCapabilityRequirement[] | undefined {\n\tif (value === undefined) return undefined;\n\tif (!Array.isArray(value)) {\n\t\tthrow new Error(`Capability plugin requires must be an array: ${manifestPath}`);\n\t}\n\tconst requirements: PluginCapabilityRequirement[] = [];\n\tconst seen = new Set<string>();\n\tfor (const [index, candidate] of value.entries()) {\n\t\tif (!isObject(candidate)) {\n\t\t\tthrow new Error(`Capability plugin requires[${index}] must be an object: ${manifestPath}`);\n\t\t}\n\t\tconst { id, version, optional } = candidate;\n\t\tassertPluginCapabilityId(id, `requires[${index}].id`, manifestPath);\n\t\tassertPluginCapabilityVersion(version, `requires[${index}].version`, manifestPath);\n\t\tif (optional !== undefined && typeof optional !== \"boolean\") {\n\t\t\tthrow new Error(`Capability plugin requires[${index}].optional must be a boolean: ${manifestPath}`);\n\t\t}\n\t\tconst key = capabilityKey(id, version);\n\t\tif (seen.has(key)) {\n\t\t\tthrow new Error(`Capability plugin requires duplicates ${id}@${version}: ${manifestPath}`);\n\t\t}\n\t\tseen.add(key);\n\t\trequirements.push(optional === undefined ? { id, version } : { id, version, optional });\n\t}\n\treturn requirements;\n}\n\n/** Parse a capability plugin manifest without accepting malformed fields. */\nexport function parseCapabilityPluginManifest(value: unknown, manifestPath = \"<manifest>\"): PluginManifest {\n\tif (!isObject(value)) throw new Error(`Capability plugin manifest must be an object: ${manifestPath}`);\n\tconst {\n\t\tid,\n\t\tversion,\n\t\tdescription,\n\t\thostVersion,\n\t\tapiVersion,\n\t\tentry,\n\t\trequiredCapabilities,\n\t\toptionalCapabilities,\n\t\tprovides,\n\t\trequires,\n\t\troles,\n\t\tagents,\n\t\tactivation,\n\t\tmanual,\n\t\tconfig,\n\t} = value;\n\tif (\n\t\ttypeof id !== \"string\" ||\n\t\ttypeof version !== \"string\" ||\n\t\ttypeof apiVersion !== \"string\" ||\n\t\ttypeof entry !== \"string\"\n\t) {\n\t\tthrow new Error(`Capability plugin manifest requires string id, version, apiVersion, and entry: ${manifestPath}`);\n\t}\n\tif (apiVersion !== EXPERIMENTAL_PUBLIC_API_VERSION) {\n\t\tthrow new Error(`Unsupported plugin API version: ${apiVersion}: ${manifestPath}`);\n\t}\n\tif (\n\t\thostVersion !== undefined &&\n\t\t(typeof hostVersion !== \"string\" || hostVersion.trim() === \"\" || validRange(hostVersion) === null)\n\t) {\n\t\tthrow new Error(\n\t\t\t`Capability plugin hostVersion must be a non-empty string containing a valid semver range (e.g. \">=0.84.0\"): ${manifestPath}`,\n\t\t);\n\t}\n\tif (requiredCapabilities !== undefined && !isStringArray(requiredCapabilities)) {\n\t\tthrow new Error(`Capability plugin requiredCapabilities must be a string array: ${manifestPath}`);\n\t}\n\tif (optionalCapabilities !== undefined && !isStringArray(optionalCapabilities)) {\n\t\tthrow new Error(`Capability plugin optionalCapabilities must be a string array: ${manifestPath}`);\n\t}\n\tif (config !== undefined && (!isObject(config) || !isJsonConfigValue(config))) {\n\t\tthrow new Error(`Capability plugin config must be a JSON object: ${manifestPath}`);\n\t}\n\tif (description !== undefined && (typeof description !== \"string\" || !description.trim())) {\n\t\tthrow new Error(`Capability plugin description must be a non-empty string: ${manifestPath}`);\n\t}\n\t// Capability cards render one system-prompt line per plugin (按需挂载与能力手册设计 §4);\n\t// an unbounded description would let a manifest bloat every request.\n\tif (description !== undefined && description.length > 200) {\n\t\tthrow new Error(`Capability plugin description must be at most 200 characters: ${manifestPath}`);\n\t}\n\tif (activation !== undefined && activation !== \"always\" && activation !== \"on-demand\") {\n\t\tthrow new Error(`Capability plugin activation must be \"always\" or \"on-demand\": ${manifestPath}`);\n\t}\n\tif (manual !== undefined && (typeof manual !== \"string\" || !manual.trim())) {\n\t\tthrow new Error(`Capability plugin manual must be a non-empty string: ${manifestPath}`);\n\t}\n\tconst parsedProvides = parsePluginCapabilityDeclarations(provides, manifestPath);\n\tconst parsedRequires = parsePluginCapabilityRequirements(requires, manifestPath);\n\tconst parsedRoles = parsePluginAgentRoles(roles, manifestPath);\n\tconst parsedAgents = parsePluginAgentDeclarations(agents, parsedRoles, manifestPath);\n\treturn {\n\t\tid,\n\t\tversion,\n\t\t...(description === undefined ? {} : { description }),\n\t\tapiVersion: apiVersion as PluginManifest[\"apiVersion\"],\n\t\tentry,\n\t\trequiredCapabilities,\n\t\toptionalCapabilities,\n\t\t...(hostVersion === undefined ? {} : { hostVersion }),\n\t\t...(parsedProvides === undefined ? {} : { provides: parsedProvides }),\n\t\t...(parsedRequires === undefined ? {} : { requires: parsedRequires }),\n\t\t...(parsedRoles === undefined ? {} : { roles: parsedRoles }),\n\t\t...(parsedAgents === undefined ? {} : { agents: parsedAgents }),\n\t\t...(activation === undefined ? {} : { activation }),\n\t\t...(manual === undefined ? {} : { manual }),\n\t\t...(config === undefined ? {} : { config: config as PluginManifest[\"config\"] }),\n\t};\n}\n"]}
@@ -143,7 +143,7 @@ function parsePluginCapabilityRequirements(value, manifestPath) {
143
143
  export function parseCapabilityPluginManifest(value, manifestPath = "<manifest>") {
144
144
  if (!isObject(value))
145
145
  throw new Error(`Capability plugin manifest must be an object: ${manifestPath}`);
146
- const { id, version, hostVersion, apiVersion, entry, requiredCapabilities, optionalCapabilities, provides, requires, roles, agents, config, } = value;
146
+ const { id, version, description, hostVersion, apiVersion, entry, requiredCapabilities, optionalCapabilities, provides, requires, roles, agents, activation, manual, config, } = value;
147
147
  if (typeof id !== "string" ||
148
148
  typeof version !== "string" ||
149
149
  typeof apiVersion !== "string" ||
@@ -166,6 +166,20 @@ export function parseCapabilityPluginManifest(value, manifestPath = "<manifest>"
166
166
  if (config !== undefined && (!isObject(config) || !isJsonConfigValue(config))) {
167
167
  throw new Error(`Capability plugin config must be a JSON object: ${manifestPath}`);
168
168
  }
169
+ if (description !== undefined && (typeof description !== "string" || !description.trim())) {
170
+ throw new Error(`Capability plugin description must be a non-empty string: ${manifestPath}`);
171
+ }
172
+ // Capability cards render one system-prompt line per plugin (按需挂载与能力手册设计 §4);
173
+ // an unbounded description would let a manifest bloat every request.
174
+ if (description !== undefined && description.length > 200) {
175
+ throw new Error(`Capability plugin description must be at most 200 characters: ${manifestPath}`);
176
+ }
177
+ if (activation !== undefined && activation !== "always" && activation !== "on-demand") {
178
+ throw new Error(`Capability plugin activation must be "always" or "on-demand": ${manifestPath}`);
179
+ }
180
+ if (manual !== undefined && (typeof manual !== "string" || !manual.trim())) {
181
+ throw new Error(`Capability plugin manual must be a non-empty string: ${manifestPath}`);
182
+ }
169
183
  const parsedProvides = parsePluginCapabilityDeclarations(provides, manifestPath);
170
184
  const parsedRequires = parsePluginCapabilityRequirements(requires, manifestPath);
171
185
  const parsedRoles = parsePluginAgentRoles(roles, manifestPath);
@@ -173,6 +187,7 @@ export function parseCapabilityPluginManifest(value, manifestPath = "<manifest>"
173
187
  return {
174
188
  id,
175
189
  version,
190
+ ...(description === undefined ? {} : { description }),
176
191
  apiVersion: apiVersion,
177
192
  entry,
178
193
  requiredCapabilities,
@@ -182,6 +197,8 @@ export function parseCapabilityPluginManifest(value, manifestPath = "<manifest>"
182
197
  ...(parsedRequires === undefined ? {} : { requires: parsedRequires }),
183
198
  ...(parsedRoles === undefined ? {} : { roles: parsedRoles }),
184
199
  ...(parsedAgents === undefined ? {} : { agents: parsedAgents }),
200
+ ...(activation === undefined ? {} : { activation }),
201
+ ...(manual === undefined ? {} : { manual }),
185
202
  ...(config === undefined ? {} : { config: config }),
186
203
  };
187
204
  }
@@ -1 +1 @@
1
- {"version":3,"file":"capability-manifest.js","sourceRoot":"","sources":["../src/capability-manifest.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Capability plugin manifest schema (plugin.json) and its pure validation.\n *\n * Authority: `@agent-forge/plugin-sdk` (D-075 S2). The host re-exports these\n * symbols from its loader module; filesystem discovery, jiti loading, and\n * lifecycle dispatch stay host-side.\n */\n\nimport { validRange } from \"semver\";\nimport type {\n\tAgentDefinitionDeclaration,\n\tPluginAgentRole,\n\tPluginCapabilityDeclaration,\n\tPluginCapabilityRequirement,\n\tPluginManifest,\n} from \"./public-api.ts\";\nimport { EXPERIMENTAL_PUBLIC_API_VERSION } from \"./public-api.ts\";\n\nfunction isStringArray(value: unknown): value is string[] {\n\treturn Array.isArray(value) && value.every((entry) => typeof entry === \"string\");\n}\n\nfunction isObject(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction isJsonConfigValue(value: unknown): boolean {\n\tif (value === null || typeof value === \"boolean\" || typeof value === \"string\") return true;\n\tif (typeof value === \"number\") return Number.isFinite(value);\n\tif (Array.isArray(value)) return value.every(isJsonConfigValue);\n\tif (!isObject(value)) return false;\n\treturn Object.values(value).every(isJsonConfigValue);\n}\n\nfunction assertPluginCapabilityId(value: unknown, field: string, manifestPath: string): asserts value is string {\n\tif (typeof value !== \"string\" || !value.trim()) {\n\t\tthrow new Error(`Capability plugin ${field} must be a non-empty string: ${manifestPath}`);\n\t}\n}\n\nfunction assertPluginCapabilityVersion(value: unknown, field: string, manifestPath: string): asserts value is number {\n\tif (typeof value !== \"number\" || !Number.isSafeInteger(value) || value < 1) {\n\t\tthrow new Error(`Capability plugin ${field} must be a positive safe integer: ${manifestPath}`);\n\t}\n}\n\nfunction capabilityKey(id: string, version: number): string {\n\treturn `${id}\\u0000${version}`;\n}\n\nfunction parsePluginAgentRoles(value: unknown, manifestPath: string): readonly PluginAgentRole[] | undefined {\n\tif (value === undefined) return undefined;\n\tif (!Array.isArray(value)) throw new Error(`Capability plugin roles must be an array: ${manifestPath}`);\n\tconst roles: PluginAgentRole[] = [];\n\tconst seen = new Set<string>();\n\tfor (const [index, role] of value.entries()) {\n\t\tif (role !== \"root-agent-controller\" && role !== \"child-agent-controller\") {\n\t\t\tthrow new Error(`Capability plugin roles[${index}] is invalid: ${manifestPath}`);\n\t\t}\n\t\tif (seen.has(role)) throw new Error(`Capability plugin roles duplicates ${role}: ${manifestPath}`);\n\t\tseen.add(role);\n\t\troles.push(role);\n\t}\n\treturn roles;\n}\n\nfunction parsePluginAgentDeclarations(\n\tvalue: unknown,\n\troles: readonly PluginAgentRole[] | undefined,\n\tmanifestPath: string,\n): readonly AgentDefinitionDeclaration[] | undefined {\n\tif (value === undefined) return undefined;\n\tif (!Array.isArray(value)) throw new Error(`Capability plugin agents must be an array: ${manifestPath}`);\n\tconst declarations: AgentDefinitionDeclaration[] = [];\n\tconst seen = new Set<string>();\n\tfor (const [index, candidate] of value.entries()) {\n\t\tif (!isObject(candidate))\n\t\t\tthrow new Error(`Capability plugin agents[${index}] must be an object: ${manifestPath}`);\n\t\tconst { id, version, role, entry } = candidate;\n\t\tassertPluginCapabilityId(id, `agents[${index}].id`, manifestPath);\n\t\tassertPluginCapabilityVersion(version, `agents[${index}].version`, manifestPath);\n\t\tif (role !== \"root-agent-controller\" && role !== \"child-agent-controller\") {\n\t\t\tthrow new Error(`Capability plugin agents[${index}].role is invalid: ${manifestPath}`);\n\t\t}\n\t\tif (typeof entry !== \"string\" || !entry.trim()) {\n\t\t\tthrow new Error(`Capability plugin agents[${index}].entry must be a non-empty string: ${manifestPath}`);\n\t\t}\n\t\tif (roles !== undefined && !roles.includes(role)) {\n\t\t\tthrow new Error(`Capability plugin agents[${index}].role is not declared in roles: ${manifestPath}`);\n\t\t}\n\t\tconst key = capabilityKey(id, version);\n\t\tif (seen.has(key)) throw new Error(`Capability plugin agents duplicates ${id}@${version}: ${manifestPath}`);\n\t\tseen.add(key);\n\t\tdeclarations.push({ id, version, role, entry });\n\t}\n\treturn declarations;\n}\n\nfunction parsePluginCapabilityDeclarations(\n\tvalue: unknown,\n\tmanifestPath: string,\n): readonly PluginCapabilityDeclaration[] | undefined {\n\tif (value === undefined) return undefined;\n\tif (!Array.isArray(value)) {\n\t\tthrow new Error(`Capability plugin provides must be an array: ${manifestPath}`);\n\t}\n\tconst declarations: PluginCapabilityDeclaration[] = [];\n\tconst seen = new Set<string>();\n\tfor (const [index, candidate] of value.entries()) {\n\t\tif (!isObject(candidate)) {\n\t\t\tthrow new Error(`Capability plugin provides[${index}] must be an object: ${manifestPath}`);\n\t\t}\n\t\tconst { id, version, kind } = candidate;\n\t\tassertPluginCapabilityId(id, `provides[${index}].id`, manifestPath);\n\t\tassertPluginCapabilityVersion(version, `provides[${index}].version`, manifestPath);\n\t\tif (kind !== \"service\" && kind !== \"contribution\" && kind !== \"transform\") {\n\t\t\tthrow new Error(`Capability plugin provides[${index}].kind is invalid: ${manifestPath}`);\n\t\t}\n\t\tconst key = capabilityKey(id, version);\n\t\tif (seen.has(key)) {\n\t\t\tthrow new Error(`Capability plugin provides duplicates ${id}@${version}: ${manifestPath}`);\n\t\t}\n\t\tseen.add(key);\n\t\tdeclarations.push({ id, version, kind });\n\t}\n\treturn declarations;\n}\n\nfunction parsePluginCapabilityRequirements(\n\tvalue: unknown,\n\tmanifestPath: string,\n): readonly PluginCapabilityRequirement[] | undefined {\n\tif (value === undefined) return undefined;\n\tif (!Array.isArray(value)) {\n\t\tthrow new Error(`Capability plugin requires must be an array: ${manifestPath}`);\n\t}\n\tconst requirements: PluginCapabilityRequirement[] = [];\n\tconst seen = new Set<string>();\n\tfor (const [index, candidate] of value.entries()) {\n\t\tif (!isObject(candidate)) {\n\t\t\tthrow new Error(`Capability plugin requires[${index}] must be an object: ${manifestPath}`);\n\t\t}\n\t\tconst { id, version, optional } = candidate;\n\t\tassertPluginCapabilityId(id, `requires[${index}].id`, manifestPath);\n\t\tassertPluginCapabilityVersion(version, `requires[${index}].version`, manifestPath);\n\t\tif (optional !== undefined && typeof optional !== \"boolean\") {\n\t\t\tthrow new Error(`Capability plugin requires[${index}].optional must be a boolean: ${manifestPath}`);\n\t\t}\n\t\tconst key = capabilityKey(id, version);\n\t\tif (seen.has(key)) {\n\t\t\tthrow new Error(`Capability plugin requires duplicates ${id}@${version}: ${manifestPath}`);\n\t\t}\n\t\tseen.add(key);\n\t\trequirements.push(optional === undefined ? { id, version } : { id, version, optional });\n\t}\n\treturn requirements;\n}\n\n/** Parse a capability plugin manifest without accepting malformed fields. */\nexport function parseCapabilityPluginManifest(value: unknown, manifestPath = \"<manifest>\"): PluginManifest {\n\tif (!isObject(value)) throw new Error(`Capability plugin manifest must be an object: ${manifestPath}`);\n\tconst {\n\t\tid,\n\t\tversion,\n\t\thostVersion,\n\t\tapiVersion,\n\t\tentry,\n\t\trequiredCapabilities,\n\t\toptionalCapabilities,\n\t\tprovides,\n\t\trequires,\n\t\troles,\n\t\tagents,\n\t\tconfig,\n\t} = value;\n\tif (\n\t\ttypeof id !== \"string\" ||\n\t\ttypeof version !== \"string\" ||\n\t\ttypeof apiVersion !== \"string\" ||\n\t\ttypeof entry !== \"string\"\n\t) {\n\t\tthrow new Error(`Capability plugin manifest requires string id, version, apiVersion, and entry: ${manifestPath}`);\n\t}\n\tif (apiVersion !== EXPERIMENTAL_PUBLIC_API_VERSION) {\n\t\tthrow new Error(`Unsupported plugin API version: ${apiVersion}: ${manifestPath}`);\n\t}\n\tif (\n\t\thostVersion !== undefined &&\n\t\t(typeof hostVersion !== \"string\" || hostVersion.trim() === \"\" || validRange(hostVersion) === null)\n\t) {\n\t\tthrow new Error(\n\t\t\t`Capability plugin hostVersion must be a non-empty string containing a valid semver range (e.g. \">=0.84.0\"): ${manifestPath}`,\n\t\t);\n\t}\n\tif (requiredCapabilities !== undefined && !isStringArray(requiredCapabilities)) {\n\t\tthrow new Error(`Capability plugin requiredCapabilities must be a string array: ${manifestPath}`);\n\t}\n\tif (optionalCapabilities !== undefined && !isStringArray(optionalCapabilities)) {\n\t\tthrow new Error(`Capability plugin optionalCapabilities must be a string array: ${manifestPath}`);\n\t}\n\tif (config !== undefined && (!isObject(config) || !isJsonConfigValue(config))) {\n\t\tthrow new Error(`Capability plugin config must be a JSON object: ${manifestPath}`);\n\t}\n\tconst parsedProvides = parsePluginCapabilityDeclarations(provides, manifestPath);\n\tconst parsedRequires = parsePluginCapabilityRequirements(requires, manifestPath);\n\tconst parsedRoles = parsePluginAgentRoles(roles, manifestPath);\n\tconst parsedAgents = parsePluginAgentDeclarations(agents, parsedRoles, manifestPath);\n\treturn {\n\t\tid,\n\t\tversion,\n\t\tapiVersion: apiVersion as PluginManifest[\"apiVersion\"],\n\t\tentry,\n\t\trequiredCapabilities,\n\t\toptionalCapabilities,\n\t\t...(hostVersion === undefined ? {} : { hostVersion }),\n\t\t...(parsedProvides === undefined ? {} : { provides: parsedProvides }),\n\t\t...(parsedRequires === undefined ? {} : { requires: parsedRequires }),\n\t\t...(parsedRoles === undefined ? {} : { roles: parsedRoles }),\n\t\t...(parsedAgents === undefined ? {} : { agents: parsedAgents }),\n\t\t...(config === undefined ? {} : { config: config as PluginManifest[\"config\"] }),\n\t};\n}\n"]}
1
+ {"version":3,"file":"capability-manifest.js","sourceRoot":"","sources":["../src/capability-manifest.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Capability plugin manifest schema (plugin.json) and its pure validation.\n *\n * Authority: `@agent-forge/plugin-sdk` (D-075 S2). The host re-exports these\n * symbols from its loader module; filesystem discovery, jiti loading, and\n * lifecycle dispatch stay host-side.\n */\n\nimport { validRange } from \"semver\";\nimport type {\n\tAgentDefinitionDeclaration,\n\tPluginAgentRole,\n\tPluginCapabilityDeclaration,\n\tPluginCapabilityRequirement,\n\tPluginManifest,\n} from \"./public-api.ts\";\nimport { EXPERIMENTAL_PUBLIC_API_VERSION } from \"./public-api.ts\";\n\nfunction isStringArray(value: unknown): value is string[] {\n\treturn Array.isArray(value) && value.every((entry) => typeof entry === \"string\");\n}\n\nfunction isObject(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction isJsonConfigValue(value: unknown): boolean {\n\tif (value === null || typeof value === \"boolean\" || typeof value === \"string\") return true;\n\tif (typeof value === \"number\") return Number.isFinite(value);\n\tif (Array.isArray(value)) return value.every(isJsonConfigValue);\n\tif (!isObject(value)) return false;\n\treturn Object.values(value).every(isJsonConfigValue);\n}\n\nfunction assertPluginCapabilityId(value: unknown, field: string, manifestPath: string): asserts value is string {\n\tif (typeof value !== \"string\" || !value.trim()) {\n\t\tthrow new Error(`Capability plugin ${field} must be a non-empty string: ${manifestPath}`);\n\t}\n}\n\nfunction assertPluginCapabilityVersion(value: unknown, field: string, manifestPath: string): asserts value is number {\n\tif (typeof value !== \"number\" || !Number.isSafeInteger(value) || value < 1) {\n\t\tthrow new Error(`Capability plugin ${field} must be a positive safe integer: ${manifestPath}`);\n\t}\n}\n\nfunction capabilityKey(id: string, version: number): string {\n\treturn `${id}\\u0000${version}`;\n}\n\nfunction parsePluginAgentRoles(value: unknown, manifestPath: string): readonly PluginAgentRole[] | undefined {\n\tif (value === undefined) return undefined;\n\tif (!Array.isArray(value)) throw new Error(`Capability plugin roles must be an array: ${manifestPath}`);\n\tconst roles: PluginAgentRole[] = [];\n\tconst seen = new Set<string>();\n\tfor (const [index, role] of value.entries()) {\n\t\tif (role !== \"root-agent-controller\" && role !== \"child-agent-controller\") {\n\t\t\tthrow new Error(`Capability plugin roles[${index}] is invalid: ${manifestPath}`);\n\t\t}\n\t\tif (seen.has(role)) throw new Error(`Capability plugin roles duplicates ${role}: ${manifestPath}`);\n\t\tseen.add(role);\n\t\troles.push(role);\n\t}\n\treturn roles;\n}\n\nfunction parsePluginAgentDeclarations(\n\tvalue: unknown,\n\troles: readonly PluginAgentRole[] | undefined,\n\tmanifestPath: string,\n): readonly AgentDefinitionDeclaration[] | undefined {\n\tif (value === undefined) return undefined;\n\tif (!Array.isArray(value)) throw new Error(`Capability plugin agents must be an array: ${manifestPath}`);\n\tconst declarations: AgentDefinitionDeclaration[] = [];\n\tconst seen = new Set<string>();\n\tfor (const [index, candidate] of value.entries()) {\n\t\tif (!isObject(candidate))\n\t\t\tthrow new Error(`Capability plugin agents[${index}] must be an object: ${manifestPath}`);\n\t\tconst { id, version, role, entry } = candidate;\n\t\tassertPluginCapabilityId(id, `agents[${index}].id`, manifestPath);\n\t\tassertPluginCapabilityVersion(version, `agents[${index}].version`, manifestPath);\n\t\tif (role !== \"root-agent-controller\" && role !== \"child-agent-controller\") {\n\t\t\tthrow new Error(`Capability plugin agents[${index}].role is invalid: ${manifestPath}`);\n\t\t}\n\t\tif (typeof entry !== \"string\" || !entry.trim()) {\n\t\t\tthrow new Error(`Capability plugin agents[${index}].entry must be a non-empty string: ${manifestPath}`);\n\t\t}\n\t\tif (roles !== undefined && !roles.includes(role)) {\n\t\t\tthrow new Error(`Capability plugin agents[${index}].role is not declared in roles: ${manifestPath}`);\n\t\t}\n\t\tconst key = capabilityKey(id, version);\n\t\tif (seen.has(key)) throw new Error(`Capability plugin agents duplicates ${id}@${version}: ${manifestPath}`);\n\t\tseen.add(key);\n\t\tdeclarations.push({ id, version, role, entry });\n\t}\n\treturn declarations;\n}\n\nfunction parsePluginCapabilityDeclarations(\n\tvalue: unknown,\n\tmanifestPath: string,\n): readonly PluginCapabilityDeclaration[] | undefined {\n\tif (value === undefined) return undefined;\n\tif (!Array.isArray(value)) {\n\t\tthrow new Error(`Capability plugin provides must be an array: ${manifestPath}`);\n\t}\n\tconst declarations: PluginCapabilityDeclaration[] = [];\n\tconst seen = new Set<string>();\n\tfor (const [index, candidate] of value.entries()) {\n\t\tif (!isObject(candidate)) {\n\t\t\tthrow new Error(`Capability plugin provides[${index}] must be an object: ${manifestPath}`);\n\t\t}\n\t\tconst { id, version, kind } = candidate;\n\t\tassertPluginCapabilityId(id, `provides[${index}].id`, manifestPath);\n\t\tassertPluginCapabilityVersion(version, `provides[${index}].version`, manifestPath);\n\t\tif (kind !== \"service\" && kind !== \"contribution\" && kind !== \"transform\") {\n\t\t\tthrow new Error(`Capability plugin provides[${index}].kind is invalid: ${manifestPath}`);\n\t\t}\n\t\tconst key = capabilityKey(id, version);\n\t\tif (seen.has(key)) {\n\t\t\tthrow new Error(`Capability plugin provides duplicates ${id}@${version}: ${manifestPath}`);\n\t\t}\n\t\tseen.add(key);\n\t\tdeclarations.push({ id, version, kind });\n\t}\n\treturn declarations;\n}\n\nfunction parsePluginCapabilityRequirements(\n\tvalue: unknown,\n\tmanifestPath: string,\n): readonly PluginCapabilityRequirement[] | undefined {\n\tif (value === undefined) return undefined;\n\tif (!Array.isArray(value)) {\n\t\tthrow new Error(`Capability plugin requires must be an array: ${manifestPath}`);\n\t}\n\tconst requirements: PluginCapabilityRequirement[] = [];\n\tconst seen = new Set<string>();\n\tfor (const [index, candidate] of value.entries()) {\n\t\tif (!isObject(candidate)) {\n\t\t\tthrow new Error(`Capability plugin requires[${index}] must be an object: ${manifestPath}`);\n\t\t}\n\t\tconst { id, version, optional } = candidate;\n\t\tassertPluginCapabilityId(id, `requires[${index}].id`, manifestPath);\n\t\tassertPluginCapabilityVersion(version, `requires[${index}].version`, manifestPath);\n\t\tif (optional !== undefined && typeof optional !== \"boolean\") {\n\t\t\tthrow new Error(`Capability plugin requires[${index}].optional must be a boolean: ${manifestPath}`);\n\t\t}\n\t\tconst key = capabilityKey(id, version);\n\t\tif (seen.has(key)) {\n\t\t\tthrow new Error(`Capability plugin requires duplicates ${id}@${version}: ${manifestPath}`);\n\t\t}\n\t\tseen.add(key);\n\t\trequirements.push(optional === undefined ? { id, version } : { id, version, optional });\n\t}\n\treturn requirements;\n}\n\n/** Parse a capability plugin manifest without accepting malformed fields. */\nexport function parseCapabilityPluginManifest(value: unknown, manifestPath = \"<manifest>\"): PluginManifest {\n\tif (!isObject(value)) throw new Error(`Capability plugin manifest must be an object: ${manifestPath}`);\n\tconst {\n\t\tid,\n\t\tversion,\n\t\tdescription,\n\t\thostVersion,\n\t\tapiVersion,\n\t\tentry,\n\t\trequiredCapabilities,\n\t\toptionalCapabilities,\n\t\tprovides,\n\t\trequires,\n\t\troles,\n\t\tagents,\n\t\tactivation,\n\t\tmanual,\n\t\tconfig,\n\t} = value;\n\tif (\n\t\ttypeof id !== \"string\" ||\n\t\ttypeof version !== \"string\" ||\n\t\ttypeof apiVersion !== \"string\" ||\n\t\ttypeof entry !== \"string\"\n\t) {\n\t\tthrow new Error(`Capability plugin manifest requires string id, version, apiVersion, and entry: ${manifestPath}`);\n\t}\n\tif (apiVersion !== EXPERIMENTAL_PUBLIC_API_VERSION) {\n\t\tthrow new Error(`Unsupported plugin API version: ${apiVersion}: ${manifestPath}`);\n\t}\n\tif (\n\t\thostVersion !== undefined &&\n\t\t(typeof hostVersion !== \"string\" || hostVersion.trim() === \"\" || validRange(hostVersion) === null)\n\t) {\n\t\tthrow new Error(\n\t\t\t`Capability plugin hostVersion must be a non-empty string containing a valid semver range (e.g. \">=0.84.0\"): ${manifestPath}`,\n\t\t);\n\t}\n\tif (requiredCapabilities !== undefined && !isStringArray(requiredCapabilities)) {\n\t\tthrow new Error(`Capability plugin requiredCapabilities must be a string array: ${manifestPath}`);\n\t}\n\tif (optionalCapabilities !== undefined && !isStringArray(optionalCapabilities)) {\n\t\tthrow new Error(`Capability plugin optionalCapabilities must be a string array: ${manifestPath}`);\n\t}\n\tif (config !== undefined && (!isObject(config) || !isJsonConfigValue(config))) {\n\t\tthrow new Error(`Capability plugin config must be a JSON object: ${manifestPath}`);\n\t}\n\tif (description !== undefined && (typeof description !== \"string\" || !description.trim())) {\n\t\tthrow new Error(`Capability plugin description must be a non-empty string: ${manifestPath}`);\n\t}\n\t// Capability cards render one system-prompt line per plugin (按需挂载与能力手册设计 §4);\n\t// an unbounded description would let a manifest bloat every request.\n\tif (description !== undefined && description.length > 200) {\n\t\tthrow new Error(`Capability plugin description must be at most 200 characters: ${manifestPath}`);\n\t}\n\tif (activation !== undefined && activation !== \"always\" && activation !== \"on-demand\") {\n\t\tthrow new Error(`Capability plugin activation must be \"always\" or \"on-demand\": ${manifestPath}`);\n\t}\n\tif (manual !== undefined && (typeof manual !== \"string\" || !manual.trim())) {\n\t\tthrow new Error(`Capability plugin manual must be a non-empty string: ${manifestPath}`);\n\t}\n\tconst parsedProvides = parsePluginCapabilityDeclarations(provides, manifestPath);\n\tconst parsedRequires = parsePluginCapabilityRequirements(requires, manifestPath);\n\tconst parsedRoles = parsePluginAgentRoles(roles, manifestPath);\n\tconst parsedAgents = parsePluginAgentDeclarations(agents, parsedRoles, manifestPath);\n\treturn {\n\t\tid,\n\t\tversion,\n\t\t...(description === undefined ? {} : { description }),\n\t\tapiVersion: apiVersion as PluginManifest[\"apiVersion\"],\n\t\tentry,\n\t\trequiredCapabilities,\n\t\toptionalCapabilities,\n\t\t...(hostVersion === undefined ? {} : { hostVersion }),\n\t\t...(parsedProvides === undefined ? {} : { provides: parsedProvides }),\n\t\t...(parsedRequires === undefined ? {} : { requires: parsedRequires }),\n\t\t...(parsedRoles === undefined ? {} : { roles: parsedRoles }),\n\t\t...(parsedAgents === undefined ? {} : { agents: parsedAgents }),\n\t\t...(activation === undefined ? {} : { activation }),\n\t\t...(manual === undefined ? {} : { manual }),\n\t\t...(config === undefined ? {} : { config: config as PluginManifest[\"config\"] }),\n\t};\n}\n"]}
package/dist/memory.d.ts CHANGED
@@ -205,6 +205,14 @@ export interface MemoryStoreV1 {
205
205
  * destroy committed atoms). Returns true when the record existed.
206
206
  */
207
207
  evict(memoryId: string): boolean;
208
+ /**
209
+ * Lists EXPIRED records owned by `query.owner`, oldest first — the optional
210
+ * read-only enumeration the retention sweep batches from (the store's own
211
+ * expiry predicate stays the single authority). Optional: replacement stores
212
+ * may omit it; the sweep then skips explicitly instead of re-deriving
213
+ * expiry outside the store.
214
+ */
215
+ listExpired?(query: MemoryStoreQuery): readonly CommittedMemoryV1[];
208
216
  }
209
217
  /** Result of `DurableMemoryLedgerV1.load`: replayable atoms plus skip diagnostics. */
210
218
  export interface DurableMemoryLedgerLoadResultV1 {
@@ -1 +1 @@
1
- {"version":3,"file":"memory.d.ts","sourceRoot":"","sources":["../src/memory.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Public contracts for the first-party memory capability (M5 Memory\n * Foundation + the builtin memory family). The plugin package\n * (`@agent-forge/plugin-memory`) is the implementation; this module is the\n * single authoring authority for its public types and the host-facing storage\n * injection contract. The host re-exports the surface from its historical\n * module paths so existing imports keep resolving.\n *\n * Types only, plus the `MEMORY_RECALL_TOOL_NAME` contract constant: the\n * recall tool name is pinned here because the host's B1 auto-recall path\n * calls it by name (`runtime.invokeTool`) and replacement memory backends\n * take over the same link by registering the same-named tool.\n *\n * Authority moved from the host's `capabilities/memory.ts` and\n * `src/memory/*` (D-075 S4 fourth batch, first slice): every symbol below is\n * a verbatim structural copy of its host definition; the transitive type\n * chain (canonical atom, store, ledger, vector components) migrated with it\n * so plugin authors never import host internals.\n */\n\nimport type { JsonValue } from \"./common.ts\";\n\n// ---------------------------------------------------------------------------\n// Canonical atom (host `src/memory/foundation.ts`)\n// ---------------------------------------------------------------------------\n\n/** Source of one memory: where the fact came from, optionally pinned by revision/digest. */\nexport interface MemorySourceRefV1 {\n\treadonly kind: \"session\" | \"entry\" | \"artifact\" | \"tool\" | \"state\";\n\treadonly id: string;\n\treadonly revision?: string;\n\treadonly digest?: string;\n}\n\n/** Namespace-scoped search facet. Facets are atom facts, never derived. */\nexport interface MemoryFacetV1 {\n\treadonly namespace: string;\n\treadonly schemaVersion: number;\n\treadonly key: string;\n\treadonly value: string;\n}\n\n/** Typed relation between atoms. Weights/validity belong to projections, not here. */\nexport interface MemoryRelationV1 {\n\treadonly relationId: string;\n\treadonly namespace: string;\n\treadonly schemaVersion: number;\n\treadonly kind: string;\n\treadonly targetMemoryId?: string;\n\treadonly targetRef?: MemorySourceRefV1;\n\treadonly confidence?: number;\n\treadonly relationRevision: string;\n}\n\nexport interface MemoryTimeRangeV1 {\n\treadonly from?: string;\n\treadonly to?: string;\n}\n\n/** Applicability narrowing; empty means \"applies without narrowing\". */\nexport interface MemoryApplicabilityV1 {\n\treadonly scenes?: readonly string[];\n\treadonly projects?: readonly string[];\n\treadonly tasks?: readonly string[];\n\treadonly timeRange?: MemoryTimeRangeV1;\n\treadonly exceptions?: readonly string[];\n}\n\n/** Preference envelope: the generic schema frozen for 1C; policy semantics come later. */\nexport interface MemoryPreferenceEnvelopeV1 {\n\treadonly subject: \"user\" | \"project\" | \"task\" | \"environment\";\n\treadonly key: string;\n\treadonly preferredValue: JsonValue;\n\treadonly alternatives?: readonly JsonValue[];\n\treadonly scope: {\n\t\treadonly level: \"task\" | \"project\" | \"scene\" | \"timeRange\" | \"profile-private\" | \"user-default\";\n\t\treadonly scenes?: readonly string[];\n\t\treadonly projects?: readonly string[];\n\t\treadonly tasks?: readonly string[];\n\t\treadonly timeRange?: MemoryTimeRangeV1;\n\t\treadonly exceptions?: readonly string[];\n\t};\n\treadonly evidence: {\n\t\treadonly class: \"explicit\" | \"repeated_behavior\" | \"inferred\";\n\t\treadonly sourceRefs: readonly MemorySourceRefV1[];\n\t\treadonly confidence: number;\n\t};\n\treadonly applicabilityConfidence: number;\n\treadonly confirmedAt?: string;\n}\n\n/** Provenance for synthesis/compaction memories derived from other atoms. */\nexport interface MemoryProvenanceV1 {\n\treadonly sourceMemoryIds: readonly string[];\n\treadonly purgeGroupId: string;\n\treadonly containsSourceContent: boolean;\n}\n\nexport type MemoryScopeV1 = \"session\" | \"cycle\" | \"long-term\";\nexport type MemoryKindV1 =\n\t| \"observation\"\n\t| \"preference\"\n\t| \"fact\"\n\t| \"decision\"\n\t| \"constraint\"\n\t| \"inference\"\n\t| \"synthesis\";\nexport type MemoryEvidenceClassV1 = \"explicit\" | \"repeated_behavior\" | \"tool_or_test\" | \"derived\";\n\n/**\n * The immutable canonical atom. Once committed, no field may change in place.\n * Field semantics follow `docs/design/记忆系统设计.md` §4 (记录模型), which is\n * the authoritative source for memory fields.\n */\nexport interface MemoryAtomV1<TPayload = JsonValue> {\n\treadonly memoryId: string;\n\treadonly contractVersion: string;\n\treadonly schemaVersion: number;\n\treadonly scope: MemoryScopeV1;\n\treadonly retentionMode: string;\n\treadonly owner: string;\n\treadonly profileId: string;\n\treadonly shareGroupId?: string;\n\t/**\n\t * Suite (方案) this atom belongs to. Absent marks a legacy pre-M5 atom:\n\t * such atoms are fail-safe INVISIBLE to every suite-scoped read and only\n\t * readable through suite-unscoped queries. The one cross-suite exception\n\t * is an explicitly promoted user-default preference.\n\t */\n\treadonly suiteId?: string;\n\treadonly retentionPolicyVersion: string;\n\treadonly memoryKind: MemoryKindV1;\n\treadonly payload: TPayload;\n\treadonly preference?: MemoryPreferenceEnvelopeV1;\n\treadonly occurredAt: string;\n\treadonly recordedAt: string;\n\treadonly sourceRefs: readonly MemorySourceRefV1[];\n\treadonly observationId: string;\n\treadonly sessionRefs: readonly string[];\n\treadonly agentInstanceRefs: readonly string[];\n\treadonly projectRefs: readonly string[];\n\treadonly subjectRefs: readonly string[];\n\treadonly facets: readonly MemoryFacetV1[];\n\treadonly relations: readonly MemoryRelationV1[];\n\treadonly provenance?: MemoryProvenanceV1;\n\treadonly confidence: number;\n\treadonly importance: number;\n\treadonly applicability?: MemoryApplicabilityV1;\n\treadonly evidenceClass: MemoryEvidenceClassV1;\n\treadonly contentRevision: string;\n\treadonly writeReason: string;\n}\n\n/**\n * Skipped-record counters attached to suite-scoped reads. The read boundary is\n * lazy and observable: excluded atoms are counted, never silently dropped.\n */\nexport interface MemorySuiteFilterStatsV1 {\n\t/** Legacy (suiteId-less) atoms skipped as invisible to any suite. */\n\treadonly legacySkipped: number;\n\t/** Atoms bound to a different suiteId that were skipped. */\n\treadonly foreignSuiteSkipped: number;\n}\n\n// ---------------------------------------------------------------------------\n// Three-scope store (host `src/memory/store.ts`)\n// ---------------------------------------------------------------------------\n\nexport interface MemoryStoreCommitOptions {\n\t/** Overrides the atom's retentionMode id at commit time (policy-selected). */\n\treadonly retentionModeId?: string;\n}\n\n/** A committed atom plus the store-assigned bookkeeping facts. */\nexport interface CommittedMemoryV1<TPayload extends JsonValue = JsonValue> {\n\treadonly atom: MemoryAtomV1<TPayload>;\n\t/** Monotonic across the whole store. */\n\treadonly storeRevision: number;\n\t/** Monotonic within the atom's scope partition. */\n\treadonly scopeRevision: number;\n\treadonly committedAt: number;\n\t/** Recall deadline computed from the retention registry. Absent = no expiry. */\n\treadonly purgeAt?: number;\n\treadonly retentionModeId: string;\n}\n\nexport interface MemoryStoreQuery {\n\treadonly owner: string;\n\t/**\n\t * Suite-scoped read boundary. When set, only atoms whose suiteId equals\n\t * this value — plus explicitly promoted user-default preferences — are\n\t * visible; legacy (suiteId-less) atoms are skipped fail-safe. When absent,\n\t * no suite filtering happens (suite-unscoped read).\n\t */\n\treadonly suiteId?: string;\n}\n\nexport interface MemoryStoreStats {\n\treadonly active: number;\n\treadonly expired: number;\n\treadonly byScope: Readonly<Record<MemoryScopeV1, { active: number; expired: number }>>;\n}\n\n/** Result of `MemoryStoreV1.listForSuite`: visible records plus skip counters. */\nexport interface MemoryStoreSuitePageV1 {\n\treadonly records: readonly CommittedMemoryV1[];\n\t/** Excluded-record counters for the suite read boundary. */\n\treadonly filter: MemorySuiteFilterStatsV1;\n}\n\nexport interface MemoryStoreV1 {\n\tcommit(atom: MemoryAtomV1, options?: MemoryStoreCommitOptions): CommittedMemoryV1;\n\t/**\n\t * Returns the record only when unexpired, owned by `query.owner`, and —\n\t * when `query.suiteId` is set — visible in that suite (legacy atoms are\n\t * invisible to every suite).\n\t */\n\tget(memoryId: string, query: MemoryStoreQuery): CommittedMemoryV1 | undefined;\n\t/** Lists active records owned by `query.owner`, optionally narrowed to one scope. */\n\tlist(query: MemoryStoreQuery, scope?: MemoryScopeV1): readonly CommittedMemoryV1[];\n\t/**\n\t * Suite-scoped listing with skip diagnostics: returns the records visible\n\t * in `query.suiteId` plus how many legacy and foreign-suite records were\n\t * excluded (expired records are excluded before the suite filter and are\n\t * not counted here).\n\t */\n\tlistForSuite(query: MemoryStoreQuery & { readonly suiteId: string }, scope?: MemoryScopeV1): MemoryStoreSuitePageV1;\n\tstats(): MemoryStoreStats;\n\t/**\n\t * Physically removes one record from the canonical in-memory ledger — the\n\t * store-side arm of the controlled purge gate (only the purge flow may\n\t * destroy committed atoms). Returns true when the record existed.\n\t */\n\tevict(memoryId: string): boolean;\n}\n\n// ---------------------------------------------------------------------------\n// Durable ledger replica (host `src/memory/ledger.ts`)\n// ---------------------------------------------------------------------------\n\n/** Result of `DurableMemoryLedgerV1.load`: replayable atoms plus skip diagnostics. */\nexport interface DurableMemoryLedgerLoadResultV1 {\n\t/** Valid atoms in file order — replay these into a fresh store. */\n\treadonly atoms: readonly MemoryAtomV1[];\n\t/** Malformed lines (invalid JSON or invalid atoms) skipped during load. */\n\treadonly corruptedLines: number;\n\t/** Atoms whose memoryId was already loaded (crash windows can duplicate appends). */\n\treadonly duplicateSkipped: number;\n\t/** True when the file existed but could not be read (permissions, IO error). */\n\treadonly unreadable: boolean;\n}\n\nexport interface DurableMemoryLedgerV1 {\n\t/**\n\t * Reads the ledger file and returns the replayable atom set plus skip\n\t * counters. A missing file is an empty ledger, not an error; malformed or\n\t * duplicate lines are skipped and counted — load NEVER throws.\n\t */\n\tload(): DurableMemoryLedgerLoadResultV1;\n\t/**\n\t * Appends one committed atom as a single JSONL line (strictly validated).\n\t * The write serializes against other processes through the `.lock` sibling\n\t * file and is fsynced before close, so an acknowledged append survives a\n\t * hard crash; a lock timeout or IO failure throws (an append never fails\n\t * silently).\n\t */\n\tappend(atom: MemoryAtomV1): void;\n\t/**\n\t * Physically rewrites the whole file with the given atoms (atomic tmp-file\n\t * + rename). The forget/purge flow calls this after removing atoms so the\n\t * durable replica matches the surviving canonical set.\n\t */\n\trewrite(atoms: readonly MemoryAtomV1[]): void;\n\t/** The ledger's current in-memory atom set (append/rewrite keep it in sync). */\n\tatomsSnapshot(): readonly MemoryAtomV1[];\n}\n\n// ---------------------------------------------------------------------------\n// Vector channel components (host `src/memory/{embedding-provider,embedding-reranker,vector-index}.ts`)\n// ---------------------------------------------------------------------------\n\n/**\n * Batch embedding provider. Implementations must be deterministic for\n * identical input and must not silently degrade: any failure propagates.\n */\nexport interface MemoryEmbeddingProviderV1 {\n\treadonly modelId: string;\n\treadonly dimensions: number;\n\t/**\n\t * Batch embed. Vectors are L2-normalized float arrays. Deterministic for\n\t * identical input. Plain text mapping — no instruction prefix is added\n\t * here; query-side instructions for bge-small-zh family are the caller's\n\t * responsibility.\n\t */\n\tembed(texts: readonly string[]): Promise<readonly (readonly number[])[]>;\n}\n\n/**\n * Minimal structural seam around a transformers.js feature-extraction\n * pipeline, so tests can inject a fake without touching the real loader.\n */\nexport interface TransformersEmbeddingBackendV1 {\n\t/** Extract features for a batch of texts; one vector per input, input order. */\n\textract: (texts: string[]) => Promise<{ toList: () => number[][] }>;\n}\n\nexport type TransformersEmbeddingLoadImpl = (\n\tmodelId: string,\n\tcacheDir: string,\n\tremoteHost: string,\n) => Promise<TransformersEmbeddingBackendV1>;\n\n/**\n * Cross-encoder reranker. Higher score = more relevant; raw logits are only\n * order-preserving, not calibrated probabilities.\n */\nexport interface MemoryRerankerV1 {\n\treadonly modelId: string;\n\t/** Score each doc against the query; higher = more relevant (raw logits, order-preserving). */\n\trerank(query: string, docs: readonly string[]): Promise<readonly number[]>;\n}\n\n/**\n * Minimal structural seam around a transformers.js sequence-classification\n * pair, so tests can inject a fake without touching the real loader.\n */\nexport interface TransformersRerankerBackendV1 {\n\t/** Score docs against the query; result[i] corresponds to docs[i]. */\n\tscore: (query: string, docs: string[]) => Promise<number[]>;\n}\n\nexport type TransformersRerankerLoadImpl = (\n\tmodelId: string,\n\tcacheDir: string,\n\tremoteHost: string,\n) => Promise<TransformersRerankerBackendV1>;\n\n/** Stored-row shape for one vector-channel upsert. */\nexport interface MemoryVectorIndexEntryV1 {\n\treadonly memoryId: string;\n\treadonly owner: string;\n\treadonly modelId: string;\n\treadonly statement: string;\n\treadonly tags: readonly string[];\n\treadonly vector: readonly number[];\n}\n\nexport interface MemoryVectorIndexQueryV1 {\n\treadonly owner: string;\n\treadonly limit: number;\n}\n\nexport interface MemoryVectorHitV1 {\n\treadonly memoryId: string;\n\treadonly score: number;\n}\n\nexport interface MemoryVectorIndexV1 {\n\treadonly replicaId: \"memory-vector-index\";\n\tupsert(entries: readonly MemoryVectorIndexEntryV1[]): Promise<void>;\n\tremove(memoryIds: readonly string[]): Promise<void>;\n\tqueryKnn(vector: readonly number[], query: MemoryVectorIndexQueryV1): Promise<readonly MemoryVectorHitV1[]>;\n\tqueryFts(queryText: string, query: MemoryVectorIndexQueryV1): Promise<readonly MemoryVectorHitV1[]>;\n\tlistMemoryIds(): Promise<ReadonlySet<string>>;\n\tcount(): Promise<number>;\n\tgetStoredModelId(): Promise<string | undefined>;\n\tclose(): Promise<void>;\n}\n\n// ---------------------------------------------------------------------------\n// Capability contracts (host `capabilities/memory.ts`)\n// ---------------------------------------------------------------------------\n\n/** 全局记忆档位: off = 家族不注册; light/full = 档位 + 开启意图。 */\nexport type MemoryModeV1 = \"off\" | \"light\" | \"full\";\n\n/**\n * 契约常量(扩展位盘点 B3):记忆召回工具名——SDK 的 B1 自动回忆按它调用\n * (`runtime.invokeTool`),替换记忆后端的插件也以同名工具接管该链路\n * (registerTool 可替换 + 同名接管)。改名即破坏该公共链路,故名入契约。\n */\nexport const MEMORY_RECALL_TOOL_NAME = \"memory_recall\";\n\n/**\n * 测试专用向量组件注入点 (架构宪法: deterministic mock AI 门禁)。注入后召回\n * 直接进入 ready 并完全由注入组件驱动, 跳过 transformers/lancedb 真实装配;\n * `reranker` 缺省 = 精排不可用 (跳过精排, 用 RRF 序)。\n */\nexport interface MemoryVectorComponentsOverrideV1 {\n\treadonly embedProvider: MemoryEmbeddingProviderV1;\n\treadonly reranker?: MemoryRerankerV1;\n\treadonly vectorIndex: MemoryVectorIndexV1;\n\treadonly queryPrefix?: string;\n}\n\n/**\n * 真实装配路径的测试缝 (enabling 状态机测试用): 组件工厂照常构建\n * (LanceDB 本地、零网络), 仅 transformers 加载被替换。\n */\nexport interface MemoryEnablingOverrideV1 {\n\treadonly embeddingLoadImpl?: TransformersEmbeddingLoadImpl;\n\treadonly rerankerLoadImpl?: TransformersRerankerLoadImpl;\n}\n\n/** Capability-level override: full vector components, or enabling-path load seams. */\nexport type MemoryCapabilityOverrideV1 = MemoryVectorComponentsOverrideV1 | MemoryEnablingOverrideV1;\n\n/**\n * 记忆底层组件注入契约 (扩展位盘点 A1/A2, D-068 增补 1): 宿主 SDK 经\n * `CreateAgentSessionOptions.memoryCapability.storage`(D-075 S4-4 起经\n * `HostCapabilities.memoryStorage`)替换记忆的持久化后端与向量组件——\n * builtin memory 保持记忆语义的编排者 (原子契约/工具面/ledger 生命周期),\n * 底层实现可换。缺省任一成员 = 内置默认实现, 默认行为零变化。工厂入参只含\n * 作用域事实 (路径域与时钟), 实现不依赖内核内部布局。\n */\nexport interface MemoryStorageComponentsV1 {\n\t/** A1: 记忆原子存取后端 (默认 = 本地内存 store + JSONL ledger 副本语义由 ledger 承担)。 */\n\treadonly storeFactory?: (scope: {\n\t\treadonly agentDir: string;\n\t\treadonly owner: string;\n\t\treadonly now: () => number;\n\t}) => MemoryStoreV1;\n\t/** A1: 持久化副本后端 (默认 = `<agentDir>/memory/<owner>/ledger-<domain>.jsonl`)。 */\n\treadonly ledgerFactory?: (scope: {\n\t\treadonly agentDir: string;\n\t\treadonly owner: string;\n\t\treadonly domain: string;\n\t\treadonly now: () => number;\n\t}) => DurableMemoryLedgerV1;\n\t/** A2: 向量通道组件 (缺省 reranker = 跳过精排, 用 RRF 序)。 */\n\treadonly vectorComponents?: MemoryVectorComponentsOverrideV1;\n}\n"]}
1
+ {"version":3,"file":"memory.d.ts","sourceRoot":"","sources":["../src/memory.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Public contracts for the first-party memory capability (M5 Memory\n * Foundation + the builtin memory family). The plugin package\n * (`@agent-forge/plugin-memory`) is the implementation; this module is the\n * single authoring authority for its public types and the host-facing storage\n * injection contract. The host re-exports the surface from its historical\n * module paths so existing imports keep resolving.\n *\n * Types only, plus the `MEMORY_RECALL_TOOL_NAME` contract constant: the\n * recall tool name is pinned here because the host's B1 auto-recall path\n * calls it by name (`runtime.invokeTool`) and replacement memory backends\n * take over the same link by registering the same-named tool.\n *\n * Authority moved from the host's `capabilities/memory.ts` and\n * `src/memory/*` (D-075 S4 fourth batch, first slice): every symbol below is\n * a verbatim structural copy of its host definition; the transitive type\n * chain (canonical atom, store, ledger, vector components) migrated with it\n * so plugin authors never import host internals.\n */\n\nimport type { JsonValue } from \"./common.ts\";\n\n// ---------------------------------------------------------------------------\n// Canonical atom (host `src/memory/foundation.ts`)\n// ---------------------------------------------------------------------------\n\n/** Source of one memory: where the fact came from, optionally pinned by revision/digest. */\nexport interface MemorySourceRefV1 {\n\treadonly kind: \"session\" | \"entry\" | \"artifact\" | \"tool\" | \"state\";\n\treadonly id: string;\n\treadonly revision?: string;\n\treadonly digest?: string;\n}\n\n/** Namespace-scoped search facet. Facets are atom facts, never derived. */\nexport interface MemoryFacetV1 {\n\treadonly namespace: string;\n\treadonly schemaVersion: number;\n\treadonly key: string;\n\treadonly value: string;\n}\n\n/** Typed relation between atoms. Weights/validity belong to projections, not here. */\nexport interface MemoryRelationV1 {\n\treadonly relationId: string;\n\treadonly namespace: string;\n\treadonly schemaVersion: number;\n\treadonly kind: string;\n\treadonly targetMemoryId?: string;\n\treadonly targetRef?: MemorySourceRefV1;\n\treadonly confidence?: number;\n\treadonly relationRevision: string;\n}\n\nexport interface MemoryTimeRangeV1 {\n\treadonly from?: string;\n\treadonly to?: string;\n}\n\n/** Applicability narrowing; empty means \"applies without narrowing\". */\nexport interface MemoryApplicabilityV1 {\n\treadonly scenes?: readonly string[];\n\treadonly projects?: readonly string[];\n\treadonly tasks?: readonly string[];\n\treadonly timeRange?: MemoryTimeRangeV1;\n\treadonly exceptions?: readonly string[];\n}\n\n/** Preference envelope: the generic schema frozen for 1C; policy semantics come later. */\nexport interface MemoryPreferenceEnvelopeV1 {\n\treadonly subject: \"user\" | \"project\" | \"task\" | \"environment\";\n\treadonly key: string;\n\treadonly preferredValue: JsonValue;\n\treadonly alternatives?: readonly JsonValue[];\n\treadonly scope: {\n\t\treadonly level: \"task\" | \"project\" | \"scene\" | \"timeRange\" | \"profile-private\" | \"user-default\";\n\t\treadonly scenes?: readonly string[];\n\t\treadonly projects?: readonly string[];\n\t\treadonly tasks?: readonly string[];\n\t\treadonly timeRange?: MemoryTimeRangeV1;\n\t\treadonly exceptions?: readonly string[];\n\t};\n\treadonly evidence: {\n\t\treadonly class: \"explicit\" | \"repeated_behavior\" | \"inferred\";\n\t\treadonly sourceRefs: readonly MemorySourceRefV1[];\n\t\treadonly confidence: number;\n\t};\n\treadonly applicabilityConfidence: number;\n\treadonly confirmedAt?: string;\n}\n\n/** Provenance for synthesis/compaction memories derived from other atoms. */\nexport interface MemoryProvenanceV1 {\n\treadonly sourceMemoryIds: readonly string[];\n\treadonly purgeGroupId: string;\n\treadonly containsSourceContent: boolean;\n}\n\nexport type MemoryScopeV1 = \"session\" | \"cycle\" | \"long-term\";\nexport type MemoryKindV1 =\n\t| \"observation\"\n\t| \"preference\"\n\t| \"fact\"\n\t| \"decision\"\n\t| \"constraint\"\n\t| \"inference\"\n\t| \"synthesis\";\nexport type MemoryEvidenceClassV1 = \"explicit\" | \"repeated_behavior\" | \"tool_or_test\" | \"derived\";\n\n/**\n * The immutable canonical atom. Once committed, no field may change in place.\n * Field semantics follow `docs/design/记忆系统设计.md` §4 (记录模型), which is\n * the authoritative source for memory fields.\n */\nexport interface MemoryAtomV1<TPayload = JsonValue> {\n\treadonly memoryId: string;\n\treadonly contractVersion: string;\n\treadonly schemaVersion: number;\n\treadonly scope: MemoryScopeV1;\n\treadonly retentionMode: string;\n\treadonly owner: string;\n\treadonly profileId: string;\n\treadonly shareGroupId?: string;\n\t/**\n\t * Suite (方案) this atom belongs to. Absent marks a legacy pre-M5 atom:\n\t * such atoms are fail-safe INVISIBLE to every suite-scoped read and only\n\t * readable through suite-unscoped queries. The one cross-suite exception\n\t * is an explicitly promoted user-default preference.\n\t */\n\treadonly suiteId?: string;\n\treadonly retentionPolicyVersion: string;\n\treadonly memoryKind: MemoryKindV1;\n\treadonly payload: TPayload;\n\treadonly preference?: MemoryPreferenceEnvelopeV1;\n\treadonly occurredAt: string;\n\treadonly recordedAt: string;\n\treadonly sourceRefs: readonly MemorySourceRefV1[];\n\treadonly observationId: string;\n\treadonly sessionRefs: readonly string[];\n\treadonly agentInstanceRefs: readonly string[];\n\treadonly projectRefs: readonly string[];\n\treadonly subjectRefs: readonly string[];\n\treadonly facets: readonly MemoryFacetV1[];\n\treadonly relations: readonly MemoryRelationV1[];\n\treadonly provenance?: MemoryProvenanceV1;\n\treadonly confidence: number;\n\treadonly importance: number;\n\treadonly applicability?: MemoryApplicabilityV1;\n\treadonly evidenceClass: MemoryEvidenceClassV1;\n\treadonly contentRevision: string;\n\treadonly writeReason: string;\n}\n\n/**\n * Skipped-record counters attached to suite-scoped reads. The read boundary is\n * lazy and observable: excluded atoms are counted, never silently dropped.\n */\nexport interface MemorySuiteFilterStatsV1 {\n\t/** Legacy (suiteId-less) atoms skipped as invisible to any suite. */\n\treadonly legacySkipped: number;\n\t/** Atoms bound to a different suiteId that were skipped. */\n\treadonly foreignSuiteSkipped: number;\n}\n\n// ---------------------------------------------------------------------------\n// Three-scope store (host `src/memory/store.ts`)\n// ---------------------------------------------------------------------------\n\nexport interface MemoryStoreCommitOptions {\n\t/** Overrides the atom's retentionMode id at commit time (policy-selected). */\n\treadonly retentionModeId?: string;\n}\n\n/** A committed atom plus the store-assigned bookkeeping facts. */\nexport interface CommittedMemoryV1<TPayload extends JsonValue = JsonValue> {\n\treadonly atom: MemoryAtomV1<TPayload>;\n\t/** Monotonic across the whole store. */\n\treadonly storeRevision: number;\n\t/** Monotonic within the atom's scope partition. */\n\treadonly scopeRevision: number;\n\treadonly committedAt: number;\n\t/** Recall deadline computed from the retention registry. Absent = no expiry. */\n\treadonly purgeAt?: number;\n\treadonly retentionModeId: string;\n}\n\nexport interface MemoryStoreQuery {\n\treadonly owner: string;\n\t/**\n\t * Suite-scoped read boundary. When set, only atoms whose suiteId equals\n\t * this value — plus explicitly promoted user-default preferences — are\n\t * visible; legacy (suiteId-less) atoms are skipped fail-safe. When absent,\n\t * no suite filtering happens (suite-unscoped read).\n\t */\n\treadonly suiteId?: string;\n}\n\nexport interface MemoryStoreStats {\n\treadonly active: number;\n\treadonly expired: number;\n\treadonly byScope: Readonly<Record<MemoryScopeV1, { active: number; expired: number }>>;\n}\n\n/** Result of `MemoryStoreV1.listForSuite`: visible records plus skip counters. */\nexport interface MemoryStoreSuitePageV1 {\n\treadonly records: readonly CommittedMemoryV1[];\n\t/** Excluded-record counters for the suite read boundary. */\n\treadonly filter: MemorySuiteFilterStatsV1;\n}\n\nexport interface MemoryStoreV1 {\n\tcommit(atom: MemoryAtomV1, options?: MemoryStoreCommitOptions): CommittedMemoryV1;\n\t/**\n\t * Returns the record only when unexpired, owned by `query.owner`, and —\n\t * when `query.suiteId` is set — visible in that suite (legacy atoms are\n\t * invisible to every suite).\n\t */\n\tget(memoryId: string, query: MemoryStoreQuery): CommittedMemoryV1 | undefined;\n\t/** Lists active records owned by `query.owner`, optionally narrowed to one scope. */\n\tlist(query: MemoryStoreQuery, scope?: MemoryScopeV1): readonly CommittedMemoryV1[];\n\t/**\n\t * Suite-scoped listing with skip diagnostics: returns the records visible\n\t * in `query.suiteId` plus how many legacy and foreign-suite records were\n\t * excluded (expired records are excluded before the suite filter and are\n\t * not counted here).\n\t */\n\tlistForSuite(query: MemoryStoreQuery & { readonly suiteId: string }, scope?: MemoryScopeV1): MemoryStoreSuitePageV1;\n\tstats(): MemoryStoreStats;\n\t/**\n\t * Physically removes one record from the canonical in-memory ledger — the\n\t * store-side arm of the controlled purge gate (only the purge flow may\n\t * destroy committed atoms). Returns true when the record existed.\n\t */\n\tevict(memoryId: string): boolean;\n\t/**\n\t * Lists EXPIRED records owned by `query.owner`, oldest first — the optional\n\t * read-only enumeration the retention sweep batches from (the store's own\n\t * expiry predicate stays the single authority). Optional: replacement stores\n\t * may omit it; the sweep then skips explicitly instead of re-deriving\n\t * expiry outside the store.\n\t */\n\tlistExpired?(query: MemoryStoreQuery): readonly CommittedMemoryV1[];\n}\n\n// ---------------------------------------------------------------------------\n// Durable ledger replica (host `src/memory/ledger.ts`)\n// ---------------------------------------------------------------------------\n\n/** Result of `DurableMemoryLedgerV1.load`: replayable atoms plus skip diagnostics. */\nexport interface DurableMemoryLedgerLoadResultV1 {\n\t/** Valid atoms in file order — replay these into a fresh store. */\n\treadonly atoms: readonly MemoryAtomV1[];\n\t/** Malformed lines (invalid JSON or invalid atoms) skipped during load. */\n\treadonly corruptedLines: number;\n\t/** Atoms whose memoryId was already loaded (crash windows can duplicate appends). */\n\treadonly duplicateSkipped: number;\n\t/** True when the file existed but could not be read (permissions, IO error). */\n\treadonly unreadable: boolean;\n}\n\nexport interface DurableMemoryLedgerV1 {\n\t/**\n\t * Reads the ledger file and returns the replayable atom set plus skip\n\t * counters. A missing file is an empty ledger, not an error; malformed or\n\t * duplicate lines are skipped and counted — load NEVER throws.\n\t */\n\tload(): DurableMemoryLedgerLoadResultV1;\n\t/**\n\t * Appends one committed atom as a single JSONL line (strictly validated).\n\t * The write serializes against other processes through the `.lock` sibling\n\t * file and is fsynced before close, so an acknowledged append survives a\n\t * hard crash; a lock timeout or IO failure throws (an append never fails\n\t * silently).\n\t */\n\tappend(atom: MemoryAtomV1): void;\n\t/**\n\t * Physically rewrites the whole file with the given atoms (atomic tmp-file\n\t * + rename). The forget/purge flow calls this after removing atoms so the\n\t * durable replica matches the surviving canonical set.\n\t */\n\trewrite(atoms: readonly MemoryAtomV1[]): void;\n\t/** The ledger's current in-memory atom set (append/rewrite keep it in sync). */\n\tatomsSnapshot(): readonly MemoryAtomV1[];\n}\n\n// ---------------------------------------------------------------------------\n// Vector channel components (host `src/memory/{embedding-provider,embedding-reranker,vector-index}.ts`)\n// ---------------------------------------------------------------------------\n\n/**\n * Batch embedding provider. Implementations must be deterministic for\n * identical input and must not silently degrade: any failure propagates.\n */\nexport interface MemoryEmbeddingProviderV1 {\n\treadonly modelId: string;\n\treadonly dimensions: number;\n\t/**\n\t * Batch embed. Vectors are L2-normalized float arrays. Deterministic for\n\t * identical input. Plain text mapping — no instruction prefix is added\n\t * here; query-side instructions for bge-small-zh family are the caller's\n\t * responsibility.\n\t */\n\tembed(texts: readonly string[]): Promise<readonly (readonly number[])[]>;\n}\n\n/**\n * Minimal structural seam around a transformers.js feature-extraction\n * pipeline, so tests can inject a fake without touching the real loader.\n */\nexport interface TransformersEmbeddingBackendV1 {\n\t/** Extract features for a batch of texts; one vector per input, input order. */\n\textract: (texts: string[]) => Promise<{ toList: () => number[][] }>;\n}\n\nexport type TransformersEmbeddingLoadImpl = (\n\tmodelId: string,\n\tcacheDir: string,\n\tremoteHost: string,\n) => Promise<TransformersEmbeddingBackendV1>;\n\n/**\n * Cross-encoder reranker. Higher score = more relevant; raw logits are only\n * order-preserving, not calibrated probabilities.\n */\nexport interface MemoryRerankerV1 {\n\treadonly modelId: string;\n\t/** Score each doc against the query; higher = more relevant (raw logits, order-preserving). */\n\trerank(query: string, docs: readonly string[]): Promise<readonly number[]>;\n}\n\n/**\n * Minimal structural seam around a transformers.js sequence-classification\n * pair, so tests can inject a fake without touching the real loader.\n */\nexport interface TransformersRerankerBackendV1 {\n\t/** Score docs against the query; result[i] corresponds to docs[i]. */\n\tscore: (query: string, docs: string[]) => Promise<number[]>;\n}\n\nexport type TransformersRerankerLoadImpl = (\n\tmodelId: string,\n\tcacheDir: string,\n\tremoteHost: string,\n) => Promise<TransformersRerankerBackendV1>;\n\n/** Stored-row shape for one vector-channel upsert. */\nexport interface MemoryVectorIndexEntryV1 {\n\treadonly memoryId: string;\n\treadonly owner: string;\n\treadonly modelId: string;\n\treadonly statement: string;\n\treadonly tags: readonly string[];\n\treadonly vector: readonly number[];\n}\n\nexport interface MemoryVectorIndexQueryV1 {\n\treadonly owner: string;\n\treadonly limit: number;\n}\n\nexport interface MemoryVectorHitV1 {\n\treadonly memoryId: string;\n\treadonly score: number;\n}\n\nexport interface MemoryVectorIndexV1 {\n\treadonly replicaId: \"memory-vector-index\";\n\tupsert(entries: readonly MemoryVectorIndexEntryV1[]): Promise<void>;\n\tremove(memoryIds: readonly string[]): Promise<void>;\n\tqueryKnn(vector: readonly number[], query: MemoryVectorIndexQueryV1): Promise<readonly MemoryVectorHitV1[]>;\n\tqueryFts(queryText: string, query: MemoryVectorIndexQueryV1): Promise<readonly MemoryVectorHitV1[]>;\n\tlistMemoryIds(): Promise<ReadonlySet<string>>;\n\tcount(): Promise<number>;\n\tgetStoredModelId(): Promise<string | undefined>;\n\tclose(): Promise<void>;\n}\n\n// ---------------------------------------------------------------------------\n// Capability contracts (host `capabilities/memory.ts`)\n// ---------------------------------------------------------------------------\n\n/** 全局记忆档位: off = 家族不注册; light/full = 档位 + 开启意图。 */\nexport type MemoryModeV1 = \"off\" | \"light\" | \"full\";\n\n/**\n * 契约常量(扩展位盘点 B3):记忆召回工具名——SDK 的 B1 自动回忆按它调用\n * (`runtime.invokeTool`),替换记忆后端的插件也以同名工具接管该链路\n * (registerTool 可替换 + 同名接管)。改名即破坏该公共链路,故名入契约。\n */\nexport const MEMORY_RECALL_TOOL_NAME = \"memory_recall\";\n\n/**\n * 测试专用向量组件注入点 (架构宪法: deterministic mock AI 门禁)。注入后召回\n * 直接进入 ready 并完全由注入组件驱动, 跳过 transformers/lancedb 真实装配;\n * `reranker` 缺省 = 精排不可用 (跳过精排, 用 RRF 序)。\n */\nexport interface MemoryVectorComponentsOverrideV1 {\n\treadonly embedProvider: MemoryEmbeddingProviderV1;\n\treadonly reranker?: MemoryRerankerV1;\n\treadonly vectorIndex: MemoryVectorIndexV1;\n\treadonly queryPrefix?: string;\n}\n\n/**\n * 真实装配路径的测试缝 (enabling 状态机测试用): 组件工厂照常构建\n * (LanceDB 本地、零网络), 仅 transformers 加载被替换。\n */\nexport interface MemoryEnablingOverrideV1 {\n\treadonly embeddingLoadImpl?: TransformersEmbeddingLoadImpl;\n\treadonly rerankerLoadImpl?: TransformersRerankerLoadImpl;\n}\n\n/** Capability-level override: full vector components, or enabling-path load seams. */\nexport type MemoryCapabilityOverrideV1 = MemoryVectorComponentsOverrideV1 | MemoryEnablingOverrideV1;\n\n/**\n * 记忆底层组件注入契约 (扩展位盘点 A1/A2, D-068 增补 1): 宿主 SDK 经\n * `CreateAgentSessionOptions.memoryCapability.storage`(D-075 S4-4 起经\n * `HostCapabilities.memoryStorage`)替换记忆的持久化后端与向量组件——\n * builtin memory 保持记忆语义的编排者 (原子契约/工具面/ledger 生命周期),\n * 底层实现可换。缺省任一成员 = 内置默认实现, 默认行为零变化。工厂入参只含\n * 作用域事实 (路径域与时钟), 实现不依赖内核内部布局。\n */\nexport interface MemoryStorageComponentsV1 {\n\t/** A1: 记忆原子存取后端 (默认 = 本地内存 store + JSONL ledger 副本语义由 ledger 承担)。 */\n\treadonly storeFactory?: (scope: {\n\t\treadonly agentDir: string;\n\t\treadonly owner: string;\n\t\treadonly now: () => number;\n\t}) => MemoryStoreV1;\n\t/** A1: 持久化副本后端 (默认 = `<agentDir>/memory/<owner>/ledger-<domain>.jsonl`)。 */\n\treadonly ledgerFactory?: (scope: {\n\t\treadonly agentDir: string;\n\t\treadonly owner: string;\n\t\treadonly domain: string;\n\t\treadonly now: () => number;\n\t}) => DurableMemoryLedgerV1;\n\t/** A2: 向量通道组件 (缺省 reranker = 跳过精排, 用 RRF 序)。 */\n\treadonly vectorComponents?: MemoryVectorComponentsOverrideV1;\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"memory.js","sourceRoot":"","sources":["../src/memory.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAsWH;;;;GAIG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAG,eAAe,CAAC","sourcesContent":["/**\n * Public contracts for the first-party memory capability (M5 Memory\n * Foundation + the builtin memory family). The plugin package\n * (`@agent-forge/plugin-memory`) is the implementation; this module is the\n * single authoring authority for its public types and the host-facing storage\n * injection contract. The host re-exports the surface from its historical\n * module paths so existing imports keep resolving.\n *\n * Types only, plus the `MEMORY_RECALL_TOOL_NAME` contract constant: the\n * recall tool name is pinned here because the host's B1 auto-recall path\n * calls it by name (`runtime.invokeTool`) and replacement memory backends\n * take over the same link by registering the same-named tool.\n *\n * Authority moved from the host's `capabilities/memory.ts` and\n * `src/memory/*` (D-075 S4 fourth batch, first slice): every symbol below is\n * a verbatim structural copy of its host definition; the transitive type\n * chain (canonical atom, store, ledger, vector components) migrated with it\n * so plugin authors never import host internals.\n */\n\nimport type { JsonValue } from \"./common.ts\";\n\n// ---------------------------------------------------------------------------\n// Canonical atom (host `src/memory/foundation.ts`)\n// ---------------------------------------------------------------------------\n\n/** Source of one memory: where the fact came from, optionally pinned by revision/digest. */\nexport interface MemorySourceRefV1 {\n\treadonly kind: \"session\" | \"entry\" | \"artifact\" | \"tool\" | \"state\";\n\treadonly id: string;\n\treadonly revision?: string;\n\treadonly digest?: string;\n}\n\n/** Namespace-scoped search facet. Facets are atom facts, never derived. */\nexport interface MemoryFacetV1 {\n\treadonly namespace: string;\n\treadonly schemaVersion: number;\n\treadonly key: string;\n\treadonly value: string;\n}\n\n/** Typed relation between atoms. Weights/validity belong to projections, not here. */\nexport interface MemoryRelationV1 {\n\treadonly relationId: string;\n\treadonly namespace: string;\n\treadonly schemaVersion: number;\n\treadonly kind: string;\n\treadonly targetMemoryId?: string;\n\treadonly targetRef?: MemorySourceRefV1;\n\treadonly confidence?: number;\n\treadonly relationRevision: string;\n}\n\nexport interface MemoryTimeRangeV1 {\n\treadonly from?: string;\n\treadonly to?: string;\n}\n\n/** Applicability narrowing; empty means \"applies without narrowing\". */\nexport interface MemoryApplicabilityV1 {\n\treadonly scenes?: readonly string[];\n\treadonly projects?: readonly string[];\n\treadonly tasks?: readonly string[];\n\treadonly timeRange?: MemoryTimeRangeV1;\n\treadonly exceptions?: readonly string[];\n}\n\n/** Preference envelope: the generic schema frozen for 1C; policy semantics come later. */\nexport interface MemoryPreferenceEnvelopeV1 {\n\treadonly subject: \"user\" | \"project\" | \"task\" | \"environment\";\n\treadonly key: string;\n\treadonly preferredValue: JsonValue;\n\treadonly alternatives?: readonly JsonValue[];\n\treadonly scope: {\n\t\treadonly level: \"task\" | \"project\" | \"scene\" | \"timeRange\" | \"profile-private\" | \"user-default\";\n\t\treadonly scenes?: readonly string[];\n\t\treadonly projects?: readonly string[];\n\t\treadonly tasks?: readonly string[];\n\t\treadonly timeRange?: MemoryTimeRangeV1;\n\t\treadonly exceptions?: readonly string[];\n\t};\n\treadonly evidence: {\n\t\treadonly class: \"explicit\" | \"repeated_behavior\" | \"inferred\";\n\t\treadonly sourceRefs: readonly MemorySourceRefV1[];\n\t\treadonly confidence: number;\n\t};\n\treadonly applicabilityConfidence: number;\n\treadonly confirmedAt?: string;\n}\n\n/** Provenance for synthesis/compaction memories derived from other atoms. */\nexport interface MemoryProvenanceV1 {\n\treadonly sourceMemoryIds: readonly string[];\n\treadonly purgeGroupId: string;\n\treadonly containsSourceContent: boolean;\n}\n\nexport type MemoryScopeV1 = \"session\" | \"cycle\" | \"long-term\";\nexport type MemoryKindV1 =\n\t| \"observation\"\n\t| \"preference\"\n\t| \"fact\"\n\t| \"decision\"\n\t| \"constraint\"\n\t| \"inference\"\n\t| \"synthesis\";\nexport type MemoryEvidenceClassV1 = \"explicit\" | \"repeated_behavior\" | \"tool_or_test\" | \"derived\";\n\n/**\n * The immutable canonical atom. Once committed, no field may change in place.\n * Field semantics follow `docs/design/记忆系统设计.md` §4 (记录模型), which is\n * the authoritative source for memory fields.\n */\nexport interface MemoryAtomV1<TPayload = JsonValue> {\n\treadonly memoryId: string;\n\treadonly contractVersion: string;\n\treadonly schemaVersion: number;\n\treadonly scope: MemoryScopeV1;\n\treadonly retentionMode: string;\n\treadonly owner: string;\n\treadonly profileId: string;\n\treadonly shareGroupId?: string;\n\t/**\n\t * Suite (方案) this atom belongs to. Absent marks a legacy pre-M5 atom:\n\t * such atoms are fail-safe INVISIBLE to every suite-scoped read and only\n\t * readable through suite-unscoped queries. The one cross-suite exception\n\t * is an explicitly promoted user-default preference.\n\t */\n\treadonly suiteId?: string;\n\treadonly retentionPolicyVersion: string;\n\treadonly memoryKind: MemoryKindV1;\n\treadonly payload: TPayload;\n\treadonly preference?: MemoryPreferenceEnvelopeV1;\n\treadonly occurredAt: string;\n\treadonly recordedAt: string;\n\treadonly sourceRefs: readonly MemorySourceRefV1[];\n\treadonly observationId: string;\n\treadonly sessionRefs: readonly string[];\n\treadonly agentInstanceRefs: readonly string[];\n\treadonly projectRefs: readonly string[];\n\treadonly subjectRefs: readonly string[];\n\treadonly facets: readonly MemoryFacetV1[];\n\treadonly relations: readonly MemoryRelationV1[];\n\treadonly provenance?: MemoryProvenanceV1;\n\treadonly confidence: number;\n\treadonly importance: number;\n\treadonly applicability?: MemoryApplicabilityV1;\n\treadonly evidenceClass: MemoryEvidenceClassV1;\n\treadonly contentRevision: string;\n\treadonly writeReason: string;\n}\n\n/**\n * Skipped-record counters attached to suite-scoped reads. The read boundary is\n * lazy and observable: excluded atoms are counted, never silently dropped.\n */\nexport interface MemorySuiteFilterStatsV1 {\n\t/** Legacy (suiteId-less) atoms skipped as invisible to any suite. */\n\treadonly legacySkipped: number;\n\t/** Atoms bound to a different suiteId that were skipped. */\n\treadonly foreignSuiteSkipped: number;\n}\n\n// ---------------------------------------------------------------------------\n// Three-scope store (host `src/memory/store.ts`)\n// ---------------------------------------------------------------------------\n\nexport interface MemoryStoreCommitOptions {\n\t/** Overrides the atom's retentionMode id at commit time (policy-selected). */\n\treadonly retentionModeId?: string;\n}\n\n/** A committed atom plus the store-assigned bookkeeping facts. */\nexport interface CommittedMemoryV1<TPayload extends JsonValue = JsonValue> {\n\treadonly atom: MemoryAtomV1<TPayload>;\n\t/** Monotonic across the whole store. */\n\treadonly storeRevision: number;\n\t/** Monotonic within the atom's scope partition. */\n\treadonly scopeRevision: number;\n\treadonly committedAt: number;\n\t/** Recall deadline computed from the retention registry. Absent = no expiry. */\n\treadonly purgeAt?: number;\n\treadonly retentionModeId: string;\n}\n\nexport interface MemoryStoreQuery {\n\treadonly owner: string;\n\t/**\n\t * Suite-scoped read boundary. When set, only atoms whose suiteId equals\n\t * this value — plus explicitly promoted user-default preferences — are\n\t * visible; legacy (suiteId-less) atoms are skipped fail-safe. When absent,\n\t * no suite filtering happens (suite-unscoped read).\n\t */\n\treadonly suiteId?: string;\n}\n\nexport interface MemoryStoreStats {\n\treadonly active: number;\n\treadonly expired: number;\n\treadonly byScope: Readonly<Record<MemoryScopeV1, { active: number; expired: number }>>;\n}\n\n/** Result of `MemoryStoreV1.listForSuite`: visible records plus skip counters. */\nexport interface MemoryStoreSuitePageV1 {\n\treadonly records: readonly CommittedMemoryV1[];\n\t/** Excluded-record counters for the suite read boundary. */\n\treadonly filter: MemorySuiteFilterStatsV1;\n}\n\nexport interface MemoryStoreV1 {\n\tcommit(atom: MemoryAtomV1, options?: MemoryStoreCommitOptions): CommittedMemoryV1;\n\t/**\n\t * Returns the record only when unexpired, owned by `query.owner`, and —\n\t * when `query.suiteId` is set — visible in that suite (legacy atoms are\n\t * invisible to every suite).\n\t */\n\tget(memoryId: string, query: MemoryStoreQuery): CommittedMemoryV1 | undefined;\n\t/** Lists active records owned by `query.owner`, optionally narrowed to one scope. */\n\tlist(query: MemoryStoreQuery, scope?: MemoryScopeV1): readonly CommittedMemoryV1[];\n\t/**\n\t * Suite-scoped listing with skip diagnostics: returns the records visible\n\t * in `query.suiteId` plus how many legacy and foreign-suite records were\n\t * excluded (expired records are excluded before the suite filter and are\n\t * not counted here).\n\t */\n\tlistForSuite(query: MemoryStoreQuery & { readonly suiteId: string }, scope?: MemoryScopeV1): MemoryStoreSuitePageV1;\n\tstats(): MemoryStoreStats;\n\t/**\n\t * Physically removes one record from the canonical in-memory ledger — the\n\t * store-side arm of the controlled purge gate (only the purge flow may\n\t * destroy committed atoms). Returns true when the record existed.\n\t */\n\tevict(memoryId: string): boolean;\n}\n\n// ---------------------------------------------------------------------------\n// Durable ledger replica (host `src/memory/ledger.ts`)\n// ---------------------------------------------------------------------------\n\n/** Result of `DurableMemoryLedgerV1.load`: replayable atoms plus skip diagnostics. */\nexport interface DurableMemoryLedgerLoadResultV1 {\n\t/** Valid atoms in file order — replay these into a fresh store. */\n\treadonly atoms: readonly MemoryAtomV1[];\n\t/** Malformed lines (invalid JSON or invalid atoms) skipped during load. */\n\treadonly corruptedLines: number;\n\t/** Atoms whose memoryId was already loaded (crash windows can duplicate appends). */\n\treadonly duplicateSkipped: number;\n\t/** True when the file existed but could not be read (permissions, IO error). */\n\treadonly unreadable: boolean;\n}\n\nexport interface DurableMemoryLedgerV1 {\n\t/**\n\t * Reads the ledger file and returns the replayable atom set plus skip\n\t * counters. A missing file is an empty ledger, not an error; malformed or\n\t * duplicate lines are skipped and counted — load NEVER throws.\n\t */\n\tload(): DurableMemoryLedgerLoadResultV1;\n\t/**\n\t * Appends one committed atom as a single JSONL line (strictly validated).\n\t * The write serializes against other processes through the `.lock` sibling\n\t * file and is fsynced before close, so an acknowledged append survives a\n\t * hard crash; a lock timeout or IO failure throws (an append never fails\n\t * silently).\n\t */\n\tappend(atom: MemoryAtomV1): void;\n\t/**\n\t * Physically rewrites the whole file with the given atoms (atomic tmp-file\n\t * + rename). The forget/purge flow calls this after removing atoms so the\n\t * durable replica matches the surviving canonical set.\n\t */\n\trewrite(atoms: readonly MemoryAtomV1[]): void;\n\t/** The ledger's current in-memory atom set (append/rewrite keep it in sync). */\n\tatomsSnapshot(): readonly MemoryAtomV1[];\n}\n\n// ---------------------------------------------------------------------------\n// Vector channel components (host `src/memory/{embedding-provider,embedding-reranker,vector-index}.ts`)\n// ---------------------------------------------------------------------------\n\n/**\n * Batch embedding provider. Implementations must be deterministic for\n * identical input and must not silently degrade: any failure propagates.\n */\nexport interface MemoryEmbeddingProviderV1 {\n\treadonly modelId: string;\n\treadonly dimensions: number;\n\t/**\n\t * Batch embed. Vectors are L2-normalized float arrays. Deterministic for\n\t * identical input. Plain text mapping — no instruction prefix is added\n\t * here; query-side instructions for bge-small-zh family are the caller's\n\t * responsibility.\n\t */\n\tembed(texts: readonly string[]): Promise<readonly (readonly number[])[]>;\n}\n\n/**\n * Minimal structural seam around a transformers.js feature-extraction\n * pipeline, so tests can inject a fake without touching the real loader.\n */\nexport interface TransformersEmbeddingBackendV1 {\n\t/** Extract features for a batch of texts; one vector per input, input order. */\n\textract: (texts: string[]) => Promise<{ toList: () => number[][] }>;\n}\n\nexport type TransformersEmbeddingLoadImpl = (\n\tmodelId: string,\n\tcacheDir: string,\n\tremoteHost: string,\n) => Promise<TransformersEmbeddingBackendV1>;\n\n/**\n * Cross-encoder reranker. Higher score = more relevant; raw logits are only\n * order-preserving, not calibrated probabilities.\n */\nexport interface MemoryRerankerV1 {\n\treadonly modelId: string;\n\t/** Score each doc against the query; higher = more relevant (raw logits, order-preserving). */\n\trerank(query: string, docs: readonly string[]): Promise<readonly number[]>;\n}\n\n/**\n * Minimal structural seam around a transformers.js sequence-classification\n * pair, so tests can inject a fake without touching the real loader.\n */\nexport interface TransformersRerankerBackendV1 {\n\t/** Score docs against the query; result[i] corresponds to docs[i]. */\n\tscore: (query: string, docs: string[]) => Promise<number[]>;\n}\n\nexport type TransformersRerankerLoadImpl = (\n\tmodelId: string,\n\tcacheDir: string,\n\tremoteHost: string,\n) => Promise<TransformersRerankerBackendV1>;\n\n/** Stored-row shape for one vector-channel upsert. */\nexport interface MemoryVectorIndexEntryV1 {\n\treadonly memoryId: string;\n\treadonly owner: string;\n\treadonly modelId: string;\n\treadonly statement: string;\n\treadonly tags: readonly string[];\n\treadonly vector: readonly number[];\n}\n\nexport interface MemoryVectorIndexQueryV1 {\n\treadonly owner: string;\n\treadonly limit: number;\n}\n\nexport interface MemoryVectorHitV1 {\n\treadonly memoryId: string;\n\treadonly score: number;\n}\n\nexport interface MemoryVectorIndexV1 {\n\treadonly replicaId: \"memory-vector-index\";\n\tupsert(entries: readonly MemoryVectorIndexEntryV1[]): Promise<void>;\n\tremove(memoryIds: readonly string[]): Promise<void>;\n\tqueryKnn(vector: readonly number[], query: MemoryVectorIndexQueryV1): Promise<readonly MemoryVectorHitV1[]>;\n\tqueryFts(queryText: string, query: MemoryVectorIndexQueryV1): Promise<readonly MemoryVectorHitV1[]>;\n\tlistMemoryIds(): Promise<ReadonlySet<string>>;\n\tcount(): Promise<number>;\n\tgetStoredModelId(): Promise<string | undefined>;\n\tclose(): Promise<void>;\n}\n\n// ---------------------------------------------------------------------------\n// Capability contracts (host `capabilities/memory.ts`)\n// ---------------------------------------------------------------------------\n\n/** 全局记忆档位: off = 家族不注册; light/full = 档位 + 开启意图。 */\nexport type MemoryModeV1 = \"off\" | \"light\" | \"full\";\n\n/**\n * 契约常量(扩展位盘点 B3):记忆召回工具名——SDK 的 B1 自动回忆按它调用\n * (`runtime.invokeTool`),替换记忆后端的插件也以同名工具接管该链路\n * (registerTool 可替换 + 同名接管)。改名即破坏该公共链路,故名入契约。\n */\nexport const MEMORY_RECALL_TOOL_NAME = \"memory_recall\";\n\n/**\n * 测试专用向量组件注入点 (架构宪法: deterministic mock AI 门禁)。注入后召回\n * 直接进入 ready 并完全由注入组件驱动, 跳过 transformers/lancedb 真实装配;\n * `reranker` 缺省 = 精排不可用 (跳过精排, 用 RRF 序)。\n */\nexport interface MemoryVectorComponentsOverrideV1 {\n\treadonly embedProvider: MemoryEmbeddingProviderV1;\n\treadonly reranker?: MemoryRerankerV1;\n\treadonly vectorIndex: MemoryVectorIndexV1;\n\treadonly queryPrefix?: string;\n}\n\n/**\n * 真实装配路径的测试缝 (enabling 状态机测试用): 组件工厂照常构建\n * (LanceDB 本地、零网络), 仅 transformers 加载被替换。\n */\nexport interface MemoryEnablingOverrideV1 {\n\treadonly embeddingLoadImpl?: TransformersEmbeddingLoadImpl;\n\treadonly rerankerLoadImpl?: TransformersRerankerLoadImpl;\n}\n\n/** Capability-level override: full vector components, or enabling-path load seams. */\nexport type MemoryCapabilityOverrideV1 = MemoryVectorComponentsOverrideV1 | MemoryEnablingOverrideV1;\n\n/**\n * 记忆底层组件注入契约 (扩展位盘点 A1/A2, D-068 增补 1): 宿主 SDK 经\n * `CreateAgentSessionOptions.memoryCapability.storage`(D-075 S4-4 起经\n * `HostCapabilities.memoryStorage`)替换记忆的持久化后端与向量组件——\n * builtin memory 保持记忆语义的编排者 (原子契约/工具面/ledger 生命周期),\n * 底层实现可换。缺省任一成员 = 内置默认实现, 默认行为零变化。工厂入参只含\n * 作用域事实 (路径域与时钟), 实现不依赖内核内部布局。\n */\nexport interface MemoryStorageComponentsV1 {\n\t/** A1: 记忆原子存取后端 (默认 = 本地内存 store + JSONL ledger 副本语义由 ledger 承担)。 */\n\treadonly storeFactory?: (scope: {\n\t\treadonly agentDir: string;\n\t\treadonly owner: string;\n\t\treadonly now: () => number;\n\t}) => MemoryStoreV1;\n\t/** A1: 持久化副本后端 (默认 = `<agentDir>/memory/<owner>/ledger-<domain>.jsonl`)。 */\n\treadonly ledgerFactory?: (scope: {\n\t\treadonly agentDir: string;\n\t\treadonly owner: string;\n\t\treadonly domain: string;\n\t\treadonly now: () => number;\n\t}) => DurableMemoryLedgerV1;\n\t/** A2: 向量通道组件 (缺省 reranker = 跳过精排, 用 RRF 序)。 */\n\treadonly vectorComponents?: MemoryVectorComponentsOverrideV1;\n}\n"]}
1
+ {"version":3,"file":"memory.js","sourceRoot":"","sources":["../src/memory.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AA8WH;;;;GAIG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAG,eAAe,CAAC","sourcesContent":["/**\n * Public contracts for the first-party memory capability (M5 Memory\n * Foundation + the builtin memory family). The plugin package\n * (`@agent-forge/plugin-memory`) is the implementation; this module is the\n * single authoring authority for its public types and the host-facing storage\n * injection contract. The host re-exports the surface from its historical\n * module paths so existing imports keep resolving.\n *\n * Types only, plus the `MEMORY_RECALL_TOOL_NAME` contract constant: the\n * recall tool name is pinned here because the host's B1 auto-recall path\n * calls it by name (`runtime.invokeTool`) and replacement memory backends\n * take over the same link by registering the same-named tool.\n *\n * Authority moved from the host's `capabilities/memory.ts` and\n * `src/memory/*` (D-075 S4 fourth batch, first slice): every symbol below is\n * a verbatim structural copy of its host definition; the transitive type\n * chain (canonical atom, store, ledger, vector components) migrated with it\n * so plugin authors never import host internals.\n */\n\nimport type { JsonValue } from \"./common.ts\";\n\n// ---------------------------------------------------------------------------\n// Canonical atom (host `src/memory/foundation.ts`)\n// ---------------------------------------------------------------------------\n\n/** Source of one memory: where the fact came from, optionally pinned by revision/digest. */\nexport interface MemorySourceRefV1 {\n\treadonly kind: \"session\" | \"entry\" | \"artifact\" | \"tool\" | \"state\";\n\treadonly id: string;\n\treadonly revision?: string;\n\treadonly digest?: string;\n}\n\n/** Namespace-scoped search facet. Facets are atom facts, never derived. */\nexport interface MemoryFacetV1 {\n\treadonly namespace: string;\n\treadonly schemaVersion: number;\n\treadonly key: string;\n\treadonly value: string;\n}\n\n/** Typed relation between atoms. Weights/validity belong to projections, not here. */\nexport interface MemoryRelationV1 {\n\treadonly relationId: string;\n\treadonly namespace: string;\n\treadonly schemaVersion: number;\n\treadonly kind: string;\n\treadonly targetMemoryId?: string;\n\treadonly targetRef?: MemorySourceRefV1;\n\treadonly confidence?: number;\n\treadonly relationRevision: string;\n}\n\nexport interface MemoryTimeRangeV1 {\n\treadonly from?: string;\n\treadonly to?: string;\n}\n\n/** Applicability narrowing; empty means \"applies without narrowing\". */\nexport interface MemoryApplicabilityV1 {\n\treadonly scenes?: readonly string[];\n\treadonly projects?: readonly string[];\n\treadonly tasks?: readonly string[];\n\treadonly timeRange?: MemoryTimeRangeV1;\n\treadonly exceptions?: readonly string[];\n}\n\n/** Preference envelope: the generic schema frozen for 1C; policy semantics come later. */\nexport interface MemoryPreferenceEnvelopeV1 {\n\treadonly subject: \"user\" | \"project\" | \"task\" | \"environment\";\n\treadonly key: string;\n\treadonly preferredValue: JsonValue;\n\treadonly alternatives?: readonly JsonValue[];\n\treadonly scope: {\n\t\treadonly level: \"task\" | \"project\" | \"scene\" | \"timeRange\" | \"profile-private\" | \"user-default\";\n\t\treadonly scenes?: readonly string[];\n\t\treadonly projects?: readonly string[];\n\t\treadonly tasks?: readonly string[];\n\t\treadonly timeRange?: MemoryTimeRangeV1;\n\t\treadonly exceptions?: readonly string[];\n\t};\n\treadonly evidence: {\n\t\treadonly class: \"explicit\" | \"repeated_behavior\" | \"inferred\";\n\t\treadonly sourceRefs: readonly MemorySourceRefV1[];\n\t\treadonly confidence: number;\n\t};\n\treadonly applicabilityConfidence: number;\n\treadonly confirmedAt?: string;\n}\n\n/** Provenance for synthesis/compaction memories derived from other atoms. */\nexport interface MemoryProvenanceV1 {\n\treadonly sourceMemoryIds: readonly string[];\n\treadonly purgeGroupId: string;\n\treadonly containsSourceContent: boolean;\n}\n\nexport type MemoryScopeV1 = \"session\" | \"cycle\" | \"long-term\";\nexport type MemoryKindV1 =\n\t| \"observation\"\n\t| \"preference\"\n\t| \"fact\"\n\t| \"decision\"\n\t| \"constraint\"\n\t| \"inference\"\n\t| \"synthesis\";\nexport type MemoryEvidenceClassV1 = \"explicit\" | \"repeated_behavior\" | \"tool_or_test\" | \"derived\";\n\n/**\n * The immutable canonical atom. Once committed, no field may change in place.\n * Field semantics follow `docs/design/记忆系统设计.md` §4 (记录模型), which is\n * the authoritative source for memory fields.\n */\nexport interface MemoryAtomV1<TPayload = JsonValue> {\n\treadonly memoryId: string;\n\treadonly contractVersion: string;\n\treadonly schemaVersion: number;\n\treadonly scope: MemoryScopeV1;\n\treadonly retentionMode: string;\n\treadonly owner: string;\n\treadonly profileId: string;\n\treadonly shareGroupId?: string;\n\t/**\n\t * Suite (方案) this atom belongs to. Absent marks a legacy pre-M5 atom:\n\t * such atoms are fail-safe INVISIBLE to every suite-scoped read and only\n\t * readable through suite-unscoped queries. The one cross-suite exception\n\t * is an explicitly promoted user-default preference.\n\t */\n\treadonly suiteId?: string;\n\treadonly retentionPolicyVersion: string;\n\treadonly memoryKind: MemoryKindV1;\n\treadonly payload: TPayload;\n\treadonly preference?: MemoryPreferenceEnvelopeV1;\n\treadonly occurredAt: string;\n\treadonly recordedAt: string;\n\treadonly sourceRefs: readonly MemorySourceRefV1[];\n\treadonly observationId: string;\n\treadonly sessionRefs: readonly string[];\n\treadonly agentInstanceRefs: readonly string[];\n\treadonly projectRefs: readonly string[];\n\treadonly subjectRefs: readonly string[];\n\treadonly facets: readonly MemoryFacetV1[];\n\treadonly relations: readonly MemoryRelationV1[];\n\treadonly provenance?: MemoryProvenanceV1;\n\treadonly confidence: number;\n\treadonly importance: number;\n\treadonly applicability?: MemoryApplicabilityV1;\n\treadonly evidenceClass: MemoryEvidenceClassV1;\n\treadonly contentRevision: string;\n\treadonly writeReason: string;\n}\n\n/**\n * Skipped-record counters attached to suite-scoped reads. The read boundary is\n * lazy and observable: excluded atoms are counted, never silently dropped.\n */\nexport interface MemorySuiteFilterStatsV1 {\n\t/** Legacy (suiteId-less) atoms skipped as invisible to any suite. */\n\treadonly legacySkipped: number;\n\t/** Atoms bound to a different suiteId that were skipped. */\n\treadonly foreignSuiteSkipped: number;\n}\n\n// ---------------------------------------------------------------------------\n// Three-scope store (host `src/memory/store.ts`)\n// ---------------------------------------------------------------------------\n\nexport interface MemoryStoreCommitOptions {\n\t/** Overrides the atom's retentionMode id at commit time (policy-selected). */\n\treadonly retentionModeId?: string;\n}\n\n/** A committed atom plus the store-assigned bookkeeping facts. */\nexport interface CommittedMemoryV1<TPayload extends JsonValue = JsonValue> {\n\treadonly atom: MemoryAtomV1<TPayload>;\n\t/** Monotonic across the whole store. */\n\treadonly storeRevision: number;\n\t/** Monotonic within the atom's scope partition. */\n\treadonly scopeRevision: number;\n\treadonly committedAt: number;\n\t/** Recall deadline computed from the retention registry. Absent = no expiry. */\n\treadonly purgeAt?: number;\n\treadonly retentionModeId: string;\n}\n\nexport interface MemoryStoreQuery {\n\treadonly owner: string;\n\t/**\n\t * Suite-scoped read boundary. When set, only atoms whose suiteId equals\n\t * this value — plus explicitly promoted user-default preferences — are\n\t * visible; legacy (suiteId-less) atoms are skipped fail-safe. When absent,\n\t * no suite filtering happens (suite-unscoped read).\n\t */\n\treadonly suiteId?: string;\n}\n\nexport interface MemoryStoreStats {\n\treadonly active: number;\n\treadonly expired: number;\n\treadonly byScope: Readonly<Record<MemoryScopeV1, { active: number; expired: number }>>;\n}\n\n/** Result of `MemoryStoreV1.listForSuite`: visible records plus skip counters. */\nexport interface MemoryStoreSuitePageV1 {\n\treadonly records: readonly CommittedMemoryV1[];\n\t/** Excluded-record counters for the suite read boundary. */\n\treadonly filter: MemorySuiteFilterStatsV1;\n}\n\nexport interface MemoryStoreV1 {\n\tcommit(atom: MemoryAtomV1, options?: MemoryStoreCommitOptions): CommittedMemoryV1;\n\t/**\n\t * Returns the record only when unexpired, owned by `query.owner`, and —\n\t * when `query.suiteId` is set — visible in that suite (legacy atoms are\n\t * invisible to every suite).\n\t */\n\tget(memoryId: string, query: MemoryStoreQuery): CommittedMemoryV1 | undefined;\n\t/** Lists active records owned by `query.owner`, optionally narrowed to one scope. */\n\tlist(query: MemoryStoreQuery, scope?: MemoryScopeV1): readonly CommittedMemoryV1[];\n\t/**\n\t * Suite-scoped listing with skip diagnostics: returns the records visible\n\t * in `query.suiteId` plus how many legacy and foreign-suite records were\n\t * excluded (expired records are excluded before the suite filter and are\n\t * not counted here).\n\t */\n\tlistForSuite(query: MemoryStoreQuery & { readonly suiteId: string }, scope?: MemoryScopeV1): MemoryStoreSuitePageV1;\n\tstats(): MemoryStoreStats;\n\t/**\n\t * Physically removes one record from the canonical in-memory ledger — the\n\t * store-side arm of the controlled purge gate (only the purge flow may\n\t * destroy committed atoms). Returns true when the record existed.\n\t */\n\tevict(memoryId: string): boolean;\n\t/**\n\t * Lists EXPIRED records owned by `query.owner`, oldest first — the optional\n\t * read-only enumeration the retention sweep batches from (the store's own\n\t * expiry predicate stays the single authority). Optional: replacement stores\n\t * may omit it; the sweep then skips explicitly instead of re-deriving\n\t * expiry outside the store.\n\t */\n\tlistExpired?(query: MemoryStoreQuery): readonly CommittedMemoryV1[];\n}\n\n// ---------------------------------------------------------------------------\n// Durable ledger replica (host `src/memory/ledger.ts`)\n// ---------------------------------------------------------------------------\n\n/** Result of `DurableMemoryLedgerV1.load`: replayable atoms plus skip diagnostics. */\nexport interface DurableMemoryLedgerLoadResultV1 {\n\t/** Valid atoms in file order — replay these into a fresh store. */\n\treadonly atoms: readonly MemoryAtomV1[];\n\t/** Malformed lines (invalid JSON or invalid atoms) skipped during load. */\n\treadonly corruptedLines: number;\n\t/** Atoms whose memoryId was already loaded (crash windows can duplicate appends). */\n\treadonly duplicateSkipped: number;\n\t/** True when the file existed but could not be read (permissions, IO error). */\n\treadonly unreadable: boolean;\n}\n\nexport interface DurableMemoryLedgerV1 {\n\t/**\n\t * Reads the ledger file and returns the replayable atom set plus skip\n\t * counters. A missing file is an empty ledger, not an error; malformed or\n\t * duplicate lines are skipped and counted — load NEVER throws.\n\t */\n\tload(): DurableMemoryLedgerLoadResultV1;\n\t/**\n\t * Appends one committed atom as a single JSONL line (strictly validated).\n\t * The write serializes against other processes through the `.lock` sibling\n\t * file and is fsynced before close, so an acknowledged append survives a\n\t * hard crash; a lock timeout or IO failure throws (an append never fails\n\t * silently).\n\t */\n\tappend(atom: MemoryAtomV1): void;\n\t/**\n\t * Physically rewrites the whole file with the given atoms (atomic tmp-file\n\t * + rename). The forget/purge flow calls this after removing atoms so the\n\t * durable replica matches the surviving canonical set.\n\t */\n\trewrite(atoms: readonly MemoryAtomV1[]): void;\n\t/** The ledger's current in-memory atom set (append/rewrite keep it in sync). */\n\tatomsSnapshot(): readonly MemoryAtomV1[];\n}\n\n// ---------------------------------------------------------------------------\n// Vector channel components (host `src/memory/{embedding-provider,embedding-reranker,vector-index}.ts`)\n// ---------------------------------------------------------------------------\n\n/**\n * Batch embedding provider. Implementations must be deterministic for\n * identical input and must not silently degrade: any failure propagates.\n */\nexport interface MemoryEmbeddingProviderV1 {\n\treadonly modelId: string;\n\treadonly dimensions: number;\n\t/**\n\t * Batch embed. Vectors are L2-normalized float arrays. Deterministic for\n\t * identical input. Plain text mapping — no instruction prefix is added\n\t * here; query-side instructions for bge-small-zh family are the caller's\n\t * responsibility.\n\t */\n\tembed(texts: readonly string[]): Promise<readonly (readonly number[])[]>;\n}\n\n/**\n * Minimal structural seam around a transformers.js feature-extraction\n * pipeline, so tests can inject a fake without touching the real loader.\n */\nexport interface TransformersEmbeddingBackendV1 {\n\t/** Extract features for a batch of texts; one vector per input, input order. */\n\textract: (texts: string[]) => Promise<{ toList: () => number[][] }>;\n}\n\nexport type TransformersEmbeddingLoadImpl = (\n\tmodelId: string,\n\tcacheDir: string,\n\tremoteHost: string,\n) => Promise<TransformersEmbeddingBackendV1>;\n\n/**\n * Cross-encoder reranker. Higher score = more relevant; raw logits are only\n * order-preserving, not calibrated probabilities.\n */\nexport interface MemoryRerankerV1 {\n\treadonly modelId: string;\n\t/** Score each doc against the query; higher = more relevant (raw logits, order-preserving). */\n\trerank(query: string, docs: readonly string[]): Promise<readonly number[]>;\n}\n\n/**\n * Minimal structural seam around a transformers.js sequence-classification\n * pair, so tests can inject a fake without touching the real loader.\n */\nexport interface TransformersRerankerBackendV1 {\n\t/** Score docs against the query; result[i] corresponds to docs[i]. */\n\tscore: (query: string, docs: string[]) => Promise<number[]>;\n}\n\nexport type TransformersRerankerLoadImpl = (\n\tmodelId: string,\n\tcacheDir: string,\n\tremoteHost: string,\n) => Promise<TransformersRerankerBackendV1>;\n\n/** Stored-row shape for one vector-channel upsert. */\nexport interface MemoryVectorIndexEntryV1 {\n\treadonly memoryId: string;\n\treadonly owner: string;\n\treadonly modelId: string;\n\treadonly statement: string;\n\treadonly tags: readonly string[];\n\treadonly vector: readonly number[];\n}\n\nexport interface MemoryVectorIndexQueryV1 {\n\treadonly owner: string;\n\treadonly limit: number;\n}\n\nexport interface MemoryVectorHitV1 {\n\treadonly memoryId: string;\n\treadonly score: number;\n}\n\nexport interface MemoryVectorIndexV1 {\n\treadonly replicaId: \"memory-vector-index\";\n\tupsert(entries: readonly MemoryVectorIndexEntryV1[]): Promise<void>;\n\tremove(memoryIds: readonly string[]): Promise<void>;\n\tqueryKnn(vector: readonly number[], query: MemoryVectorIndexQueryV1): Promise<readonly MemoryVectorHitV1[]>;\n\tqueryFts(queryText: string, query: MemoryVectorIndexQueryV1): Promise<readonly MemoryVectorHitV1[]>;\n\tlistMemoryIds(): Promise<ReadonlySet<string>>;\n\tcount(): Promise<number>;\n\tgetStoredModelId(): Promise<string | undefined>;\n\tclose(): Promise<void>;\n}\n\n// ---------------------------------------------------------------------------\n// Capability contracts (host `capabilities/memory.ts`)\n// ---------------------------------------------------------------------------\n\n/** 全局记忆档位: off = 家族不注册; light/full = 档位 + 开启意图。 */\nexport type MemoryModeV1 = \"off\" | \"light\" | \"full\";\n\n/**\n * 契约常量(扩展位盘点 B3):记忆召回工具名——SDK 的 B1 自动回忆按它调用\n * (`runtime.invokeTool`),替换记忆后端的插件也以同名工具接管该链路\n * (registerTool 可替换 + 同名接管)。改名即破坏该公共链路,故名入契约。\n */\nexport const MEMORY_RECALL_TOOL_NAME = \"memory_recall\";\n\n/**\n * 测试专用向量组件注入点 (架构宪法: deterministic mock AI 门禁)。注入后召回\n * 直接进入 ready 并完全由注入组件驱动, 跳过 transformers/lancedb 真实装配;\n * `reranker` 缺省 = 精排不可用 (跳过精排, 用 RRF 序)。\n */\nexport interface MemoryVectorComponentsOverrideV1 {\n\treadonly embedProvider: MemoryEmbeddingProviderV1;\n\treadonly reranker?: MemoryRerankerV1;\n\treadonly vectorIndex: MemoryVectorIndexV1;\n\treadonly queryPrefix?: string;\n}\n\n/**\n * 真实装配路径的测试缝 (enabling 状态机测试用): 组件工厂照常构建\n * (LanceDB 本地、零网络), 仅 transformers 加载被替换。\n */\nexport interface MemoryEnablingOverrideV1 {\n\treadonly embeddingLoadImpl?: TransformersEmbeddingLoadImpl;\n\treadonly rerankerLoadImpl?: TransformersRerankerLoadImpl;\n}\n\n/** Capability-level override: full vector components, or enabling-path load seams. */\nexport type MemoryCapabilityOverrideV1 = MemoryVectorComponentsOverrideV1 | MemoryEnablingOverrideV1;\n\n/**\n * 记忆底层组件注入契约 (扩展位盘点 A1/A2, D-068 增补 1): 宿主 SDK 经\n * `CreateAgentSessionOptions.memoryCapability.storage`(D-075 S4-4 起经\n * `HostCapabilities.memoryStorage`)替换记忆的持久化后端与向量组件——\n * builtin memory 保持记忆语义的编排者 (原子契约/工具面/ledger 生命周期),\n * 底层实现可换。缺省任一成员 = 内置默认实现, 默认行为零变化。工厂入参只含\n * 作用域事实 (路径域与时钟), 实现不依赖内核内部布局。\n */\nexport interface MemoryStorageComponentsV1 {\n\t/** A1: 记忆原子存取后端 (默认 = 本地内存 store + JSONL ledger 副本语义由 ledger 承担)。 */\n\treadonly storeFactory?: (scope: {\n\t\treadonly agentDir: string;\n\t\treadonly owner: string;\n\t\treadonly now: () => number;\n\t}) => MemoryStoreV1;\n\t/** A1: 持久化副本后端 (默认 = `<agentDir>/memory/<owner>/ledger-<domain>.jsonl`)。 */\n\treadonly ledgerFactory?: (scope: {\n\t\treadonly agentDir: string;\n\t\treadonly owner: string;\n\t\treadonly domain: string;\n\t\treadonly now: () => number;\n\t}) => DurableMemoryLedgerV1;\n\t/** A2: 向量通道组件 (缺省 reranker = 跳过精排, 用 RRF 序)。 */\n\treadonly vectorComponents?: MemoryVectorComponentsOverrideV1;\n}\n"]}
@@ -59,6 +59,12 @@ export interface AgentDefinitionDeclaration {
59
59
  export interface PluginManifest {
60
60
  id: string;
61
61
  version: string;
62
+ /**
63
+ * One-line human/AI-facing capability summary (按需挂载与能力手册设计 §4).
64
+ * Feeds the capability card shown for `activation: "on-demand"` plugins in
65
+ * the system prompt; optional, first non-empty line wins.
66
+ */
67
+ description?: string;
62
68
  /**
63
69
  * Semver range of host (agent-forge application) versions this plugin
64
70
  * supports, e.g. `">=0.84.0 <1.0.0"`. When declared and the running host
@@ -79,6 +85,17 @@ export interface PluginManifest {
79
85
  roles?: readonly PluginAgentRole[];
80
86
  /** Experimental Agent definitions that the plugin factory may register. */
81
87
  agents?: readonly AgentDefinitionDeclaration[];
88
+ /**
89
+ * Tool-surface activation mode (插件按需挂载与能力手册设计 §5.1): `"always"`
90
+ * (default) puts the plugin's tools into the initial active tool set;
91
+ * `"on-demand"` registers them into the registry only — the model sees a
92
+ * one-line capability card and pulls the full tool set in through
93
+ * `capability_mount`. A declaration by the plugin about its own surface
94
+ * weight; there is no user-facing switch.
95
+ */
96
+ activation?: "always" | "on-demand";
97
+ /** Path to the AI manual (relative to the manifest), returned by `capability_mount`. */
98
+ manual?: string;
82
99
  config?: PluginConfig;
83
100
  }
84
101
  /**
@@ -779,6 +796,12 @@ export interface OutputArtifactRef {
779
796
  kind: string;
780
797
  mediaType: string;
781
798
  sizeBytes?: number;
799
+ /**
800
+ * Runtime-computed. On `output.put` the host buffers at most 1 MiB and sets
801
+ * this flag itself whenever the ceiling trips (oversized payloads keep a
802
+ * head+marker+tail resident view while `sizeBytes` stays the original
803
+ * total), so a caller-provided value is type-checked but always overridden.
804
+ */
782
805
  truncated: boolean;
783
806
  createdAt: number;
784
807
  }
@@ -866,6 +889,16 @@ export interface BuildSystemPromptOptions {
866
889
  }>;
867
890
  /** Pre-loaded skills. */
868
891
  skills?: readonly BuildSystemPromptSkill[];
892
+ /**
893
+ * Mountable capability cards (插件按需挂载与能力手册设计 §4) — one line per
894
+ * `activation: "on-demand"` plugin whose tools are currently deferred. The
895
+ * caller filters to still-deferred cards; mounted ones disappear on the
896
+ * next prompt rebuild.
897
+ */
898
+ capabilityCards?: readonly {
899
+ pluginId: string;
900
+ description?: string;
901
+ }[];
869
902
  }
870
903
  /**
871
904
  * Public session mechanism. Product state remains plugin-owned and is written