🔒 fix: Address Codex re-review on memory capability (round 5)

- Gate inline memory registration (memoryAvailable) on the memory WRITE permissions (USE+CREATE+UPDATE), so a read-only-memory role no longer has set_memory/delete_memory shown to the model only for the runtime loader to refuse them (api/server/services/Endpoints/agents/initialize.js).
- Enforce the per-agent memory opt-in at execution: handleTools now refuses to construct set_memory/delete_memory unless the agent actually declared them (toolDefinitions/tools), blocking hallucinated/undeclared memory tool calls from mutating memory.
- Fail closed when getFormattedMemories errors with a configured tokenLimit, instead of writing as if storage were empty and bypassing the cap (api/app/clients/tools/util/handleTools.js).
This commit is contained in:
Danny Avila 2026-06-20 23:36:14 -04:00
parent e52ca9d3d2
commit 74e6744150
2 changed files with 35 additions and 6 deletions

View file

@ -153,9 +153,12 @@ const initializeClient = async ({ req, res, signal, endpointOption }) => {
const skillDbMethods = getSkillDbMethods();
/** Run-level gate for inline memory tools: the `memory` capability must be
* enabled, memory must be configured, and the user must not have opted out
* or lost the `MEMORIES.USE` permission. Agents (or the ephemeral memory
* badge) opt in per-agent via the `memory` marker on `tools`. */
* enabled, memory must be configured, and the user must not have opted out.
* Requires the memory WRITE permissions (CREATE + UPDATE) both inline tools
* mutate memory so the tools aren't registered (and shown to the model) for
* read-only-memory roles that the runtime loader would then refuse to build.
* Agents (or the ephemeral memory badge) opt in per-agent via the `memory`
* marker on `tools`. */
const memoryAvailable =
enabledCapabilities.has(AgentCapabilities.memory) &&
isMemoryEnabled(appConfig?.memory) &&
@ -163,7 +166,7 @@ const initializeClient = async ({ req, res, signal, endpointOption }) => {
(await checkAccess({
user: req.user,
permissionType: PermissionTypes.MEMORIES,
permissions: [Permissions.USE],
permissions: [Permissions.USE, Permissions.CREATE, Permissions.UPDATE],
getRoleByName: db.getRoleByName,
}));