Graph Weaken
graph_weakenReduce the weight of a graph edge when the user corrects a recalled fact, such as saying 'no' or 'that's wrong'. Persists immediately with weight clamped at 0.0.
Instructions
Decrease an edge's weight when the user corrects a recalled fact. Call this when the user says 'no', 'that's wrong', or corrects something from the graph. Persists immediately; weight clamps at 0.0. Returns an error if the edge doesn't exist — use graph_delete to remove an entity outright. To replace a fact rather than weaken it, prefer graph_relate with the new fact and SUPERSEDES.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| from_name | Yes | Source entity name or ID | |
| to_name | Yes | Target entity name or ID | |
| relation | Yes | Relationship type | |
| amount | No | Weaken amount (default: 0.3) | |
| reason | No | Why weakening |
Implementation Reference
- src/shared/neo4j-client.ts:569-594 (handler)The `weaken` method on Neo4jClient — the core logic. It executes a Cypher query that finds the edge (tenant-scoped), subtracts `amount` from its weight (clamping at 0.0), updates `last_confirmed`, and returns previous/new weight. Throws if edge not found.
async weaken( tenantId: string, fromId: string, toId: string, type: RelationshipType, amount?: number, ): Promise<{ previous_weight: number; new_weight: number }> { const config = getConfig(); const weakenAmount = amount ?? config.weights.weaken_on_correct; const rows = await this.run( ` MATCH (a:Entity {tenant_id: $tenantId, id: $fromId})-[r:\`${type}\`]->(b:Entity {tenant_id: $tenantId, id: $toId}) WITH r, r.weight AS old_weight SET r.weight = CASE WHEN r.weight - $amount < 0.0 THEN 0.0 ELSE r.weight - $amount END, r.last_confirmed = datetime() RETURN old_weight, r.weight AS new_weight `, { tenantId, fromId, toId, amount: weakenAmount }, ); const row = rows[0]; if (!row) throw new Error(`Edge not found: ${fromId} -[${type}]-> ${toId} in tenant ${tenantId}`); return { previous_weight: Number(row["old_weight"]), new_weight: Number(row["new_weight"]), }; } - src/mcp-server/index.ts:369-398 (handler)The `graph_weaken` tool handler — the MCP tool's async callback. Resolves entity names to IDs (via findEntityIdByName or slugify), delegates to `client.weaken()`, and returns the result with a `pruned` flag.
// ─── Tool: graph_weaken ─── server.registerTool("graph_weaken", { title: "Graph Weaken", description: "Decrease an edge's weight when the user corrects a recalled fact. Call this when the user says 'no', 'that's wrong', or corrects something from the graph. Persists immediately; weight clamps at 0.0. Returns an error if the edge doesn't exist — use graph_delete to remove an entity outright. To replace a fact rather than weaken it, prefer graph_relate with the new fact and SUPERSEDES.", inputSchema: { from_name: z.string().describe("Source entity name or ID"), to_name: z.string().describe("Target entity name or ID"), relation: z.string().describe("Relationship type"), amount: z.number().optional().default(0.3).describe("Weaken amount (default: 0.3)"), reason: z.string().optional().describe("Why weakening"), }, annotations: { idempotentHint: true }, }, async (args) => { try { const tenantId = currentTenant(); const fromId = (await client.findEntityIdByName(tenantId, args.from_name)) ?? slugify(args.from_name); const toId = (await client.findEntityIdByName(tenantId, args.to_name)) ?? slugify(args.to_name); const result = await client.weaken(tenantId, fromId, toId, args.relation as RelationshipType, args.amount); return toolResult({ previous_weight: result.previous_weight, new_weight: result.new_weight, edge: { from: fromId, to: toId, type: args.relation }, pruned: result.new_weight <= 0.05, }); } catch (err) { return toolError(`graph_weaken failed: ${err instanceof Error ? err.message : String(err)}`); } }); - src/mcp-server/index.ts:375-381 (schema)Input schema for graph_weaken using Zod: `from_name`, `to_name`, `relation` (required strings), `amount` (optional number, default 0.3), `reason` (optional string).
inputSchema: { from_name: z.string().describe("Source entity name or ID"), to_name: z.string().describe("Target entity name or ID"), relation: z.string().describe("Relationship type"), amount: z.number().optional().default(0.3).describe("Weaken amount (default: 0.3)"), reason: z.string().optional().describe("Why weakening"), }, - src/mcp-server/index.ts:371-398 (registration)Registration of the graph_weaken tool via `server.registerTool('graph_weaken', ...)` on the MCP server instance.
server.registerTool("graph_weaken", { title: "Graph Weaken", description: "Decrease an edge's weight when the user corrects a recalled fact. Call this when the user says 'no', 'that's wrong', or corrects something from the graph. Persists immediately; weight clamps at 0.0. Returns an error if the edge doesn't exist — use graph_delete to remove an entity outright. To replace a fact rather than weaken it, prefer graph_relate with the new fact and SUPERSEDES.", inputSchema: { from_name: z.string().describe("Source entity name or ID"), to_name: z.string().describe("Target entity name or ID"), relation: z.string().describe("Relationship type"), amount: z.number().optional().default(0.3).describe("Weaken amount (default: 0.3)"), reason: z.string().optional().describe("Why weakening"), }, annotations: { idempotentHint: true }, }, async (args) => { try { const tenantId = currentTenant(); const fromId = (await client.findEntityIdByName(tenantId, args.from_name)) ?? slugify(args.from_name); const toId = (await client.findEntityIdByName(tenantId, args.to_name)) ?? slugify(args.to_name); const result = await client.weaken(tenantId, fromId, toId, args.relation as RelationshipType, args.amount); return toolResult({ previous_weight: result.previous_weight, new_weight: result.new_weight, edge: { from: fromId, to: toId, type: args.relation }, pruned: result.new_weight <= 0.05, }); } catch (err) { return toolError(`graph_weaken failed: ${err instanceof Error ? err.message : String(err)}`); } }); - src/shared/config.ts:54-62 (helper)Default config value `weaken_on_correct: 0.3` — the default weaken amount used when the tool's `amount` parameter is not provided.
weights: { explicit_statement: 0.7, inferred: 0.3, from_memory_file: 0.5, boost_on_confirm: 0.15, boost_on_mention: 0.05, weaken_on_correct: 0.3, project_context_boost: 0.1, },