@atbash/atbash-langgraph 0.0.5-dev.3 → 0.0.5-dev.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +21 -1
- package/dist/index.js +79 -4
- package/package.json +2 -2
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as _langchain_core_messages from '@langchain/core/messages';
|
|
2
2
|
import * as _langchain_langgraph from '@langchain/langgraph';
|
|
3
3
|
import { StateGraph } from '@langchain/langgraph';
|
|
4
|
-
import { Atbash } from '@atbash/sdk';
|
|
4
|
+
import { Atbash, MemoryGuardManager } from '@atbash/sdk';
|
|
5
5
|
import * as _langchain_core_tools from '@langchain/core/tools';
|
|
6
6
|
import { z } from 'zod';
|
|
7
7
|
|
|
@@ -16,6 +16,7 @@ type AtbashState = typeof AtbashStateAnnotation.State;
|
|
|
16
16
|
|
|
17
17
|
interface GuardNodeOptions {
|
|
18
18
|
client: Atbash;
|
|
19
|
+
guardManager?: MemoryGuardManager;
|
|
19
20
|
}
|
|
20
21
|
declare function createGuardNode(opts: GuardNodeOptions): (state: AtbashState) => Promise<Partial<AtbashState>>;
|
|
21
22
|
|
|
@@ -29,6 +30,25 @@ interface AtbashSafetyOptions {
|
|
|
29
30
|
endpoint?: string;
|
|
30
31
|
toolsNode?: string;
|
|
31
32
|
agentNode?: string;
|
|
33
|
+
/** Agent workspace directory — `~` is expanded. Defaults to `process.cwd()`. */
|
|
34
|
+
workspaceDir?: string;
|
|
35
|
+
/** Explicit MEMORY.md path. Overrides `workspaceDir/MEMORY.md`. */
|
|
36
|
+
memoryFilePath?: string;
|
|
37
|
+
/** How long (ms) to trust the local pointer between chain checks. Default 30000. */
|
|
38
|
+
memorySyncTTLMs?: number;
|
|
39
|
+
/** Block memory reads when a rolled-back version scores below this (1–10). Default 1 = warn only. */
|
|
40
|
+
memoryRollbackMinScore?: number;
|
|
41
|
+
/** Custom memory path patterns. Defaults to SDK built-ins. */
|
|
42
|
+
memoryPathPatterns?: string[];
|
|
43
|
+
/** Optional judge endpoint override. */
|
|
44
|
+
judgeEndpoint?: string;
|
|
45
|
+
/** Self-hosted judge response-signing pubkey (required when judgeEndpoint uses "self-hosted" policy). */
|
|
46
|
+
judgeVerifyPubKey?: string;
|
|
47
|
+
/** Organization name for chain resolution (public vs private chain). */
|
|
48
|
+
orgName?: string;
|
|
49
|
+
/** false = monitor mode: log but never block. Default true. */
|
|
50
|
+
enforce?: boolean;
|
|
51
|
+
debug?: boolean;
|
|
32
52
|
}
|
|
33
53
|
declare function addAtbashSafety(builder: StateGraph<AtbashState>, opts: AtbashSafetyOptions): StateGraph<_langchain_langgraph.StateType<{
|
|
34
54
|
atbashVerdict: _langchain_langgraph.BaseChannel<string | null, string | _langchain_langgraph.OverwriteValue<string | null> | null, unknown>;
|
package/dist/index.js
CHANGED
|
@@ -21,6 +21,7 @@ var AtbashStateAnnotation = Annotation.Root({
|
|
|
21
21
|
});
|
|
22
22
|
|
|
23
23
|
// src/nodes/guardNode.ts
|
|
24
|
+
import { MemoryIntegrityError } from "@atbash/sdk";
|
|
24
25
|
import { ToolMessage } from "@langchain/core/messages";
|
|
25
26
|
import { isGraphBubbleUp } from "@langchain/langgraph";
|
|
26
27
|
function createGuardNode(opts) {
|
|
@@ -33,11 +34,64 @@ function createGuardNode(opts) {
|
|
|
33
34
|
atbashReason: "No tool calls detected"
|
|
34
35
|
};
|
|
35
36
|
}
|
|
36
|
-
const
|
|
37
|
+
const memoryHandledIds = /* @__PURE__ */ new Set();
|
|
38
|
+
if (opts.guardManager) {
|
|
39
|
+
for (const tc of toolCalls) {
|
|
40
|
+
let memDecision;
|
|
41
|
+
try {
|
|
42
|
+
memDecision = await opts.guardManager.handleBeforeToolCall(
|
|
43
|
+
{ toolName: tc.name, args: tc.args },
|
|
44
|
+
{}
|
|
45
|
+
);
|
|
46
|
+
} catch (err) {
|
|
47
|
+
const reason = err instanceof Error ? err.message : String(err);
|
|
48
|
+
const verdict = err instanceof MemoryIntegrityError ? "BLOCK" : "ERROR";
|
|
49
|
+
return {
|
|
50
|
+
messages: toolCalls.map(
|
|
51
|
+
(toolCall) => new ToolMessage({
|
|
52
|
+
tool_call_id: toolCall.id,
|
|
53
|
+
content: toolCall.id === tc.id ? `Memory guard error: ${reason}` : "Blocked \u2014 memory safety check failed for another tool call"
|
|
54
|
+
})
|
|
55
|
+
),
|
|
56
|
+
atbashVerdict: verdict,
|
|
57
|
+
atbashReason: `Memory guard error: ${reason}`,
|
|
58
|
+
atbashToolCallId: null,
|
|
59
|
+
atbashConfidence: null
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
if (memDecision !== null) {
|
|
63
|
+
if (memDecision.block) {
|
|
64
|
+
return {
|
|
65
|
+
messages: toolCalls.map(
|
|
66
|
+
(toolCall) => new ToolMessage({
|
|
67
|
+
tool_call_id: toolCall.id,
|
|
68
|
+
content: toolCall.id === tc.id ? `Memory write blocked by Atbash: ${memDecision.blockReason ?? ""}` : "Blocked \u2014 another tool call was blocked by memory safety"
|
|
69
|
+
})
|
|
70
|
+
),
|
|
71
|
+
atbashVerdict: "BLOCK",
|
|
72
|
+
atbashReason: memDecision.blockReason ?? "memory write blocked",
|
|
73
|
+
atbashToolCallId: null,
|
|
74
|
+
atbashConfidence: null
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
memoryHandledIds.add(tc.id);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
const auditCalls = toolCalls.filter((tc) => !memoryHandledIds.has(tc.id));
|
|
82
|
+
if (auditCalls.length === 0) {
|
|
83
|
+
return {
|
|
84
|
+
atbashVerdict: "ALLOW",
|
|
85
|
+
atbashReason: "Memory operations validated by guard",
|
|
86
|
+
atbashToolCallId: null,
|
|
87
|
+
atbashConfidence: null
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
const actionText = auditCalls.map((toolCall) => `${toolCall.name}(${JSON.stringify(toolCall.args)})`).join("; ");
|
|
37
91
|
try {
|
|
38
92
|
const decision = await opts.client.auditToolCall({
|
|
39
|
-
toolName:
|
|
40
|
-
args:
|
|
93
|
+
toolName: auditCalls.map((t) => t.name).join(",") || "langgraph_batch",
|
|
94
|
+
args: auditCalls,
|
|
41
95
|
context: `LangGraph agent attempting: ${actionText}`
|
|
42
96
|
});
|
|
43
97
|
if (decision.verdict === "BLOCK" || decision.verdict === "ERROR") {
|
|
@@ -126,9 +180,14 @@ function createAuditNode(opts) {
|
|
|
126
180
|
// src/builder.ts
|
|
127
181
|
import {
|
|
128
182
|
Atbash,
|
|
183
|
+
createMemoryGuardManager,
|
|
129
184
|
setupTelemetry,
|
|
130
185
|
shutdownTelemetry
|
|
131
186
|
} from "@atbash/sdk";
|
|
187
|
+
import { homedir } from "os";
|
|
188
|
+
function expandHome(p) {
|
|
189
|
+
return p.replace(/^~(?=\/|$)/, homedir());
|
|
190
|
+
}
|
|
132
191
|
function addAtbashSafety(builder, opts) {
|
|
133
192
|
setupTelemetry({ enabled: true, source: "plugin:langgraph" });
|
|
134
193
|
process.once("beforeExit", () => shutdownTelemetry());
|
|
@@ -138,10 +197,26 @@ function addAtbashSafety(builder, opts) {
|
|
|
138
197
|
const clientOpts = {};
|
|
139
198
|
if (opts.endpoint) clientOpts.endpoint = opts.endpoint;
|
|
140
199
|
const client = new Atbash(privkey, clientOpts);
|
|
200
|
+
const guard = createMemoryGuardManager({
|
|
201
|
+
auth: client.auth,
|
|
202
|
+
workspaceDir: opts.workspaceDir ? expandHome(opts.workspaceDir) : process.cwd(),
|
|
203
|
+
...opts.memoryFilePath ? { memoryFilePath: expandHome(opts.memoryFilePath) } : {},
|
|
204
|
+
...opts.memorySyncTTLMs !== void 0 ? { ttlMs: opts.memorySyncTTLMs } : {},
|
|
205
|
+
...opts.memoryRollbackMinScore !== void 0 ? { rollbackMinScore: opts.memoryRollbackMinScore } : {},
|
|
206
|
+
...opts.memoryPathPatterns ? { memoryPathPatterns: opts.memoryPathPatterns } : {},
|
|
207
|
+
...opts.judgeEndpoint ? { judgeEndpoint: opts.judgeEndpoint } : {},
|
|
208
|
+
...opts.judgeVerifyPubKey ? { judgeVerifyPubKey: opts.judgeVerifyPubKey } : {},
|
|
209
|
+
...opts.orgName ? { orgName: opts.orgName } : {},
|
|
210
|
+
enforce: opts.enforce ?? true,
|
|
211
|
+
debug: opts.debug ?? false
|
|
212
|
+
});
|
|
213
|
+
guard.runBootProbe().catch((err) => {
|
|
214
|
+
console.warn("[atbash] boot probe failed:", err instanceof Error ? err.message : String(err));
|
|
215
|
+
});
|
|
141
216
|
const graph = builder;
|
|
142
217
|
const toolsNode = opts.toolsNode ?? "tools";
|
|
143
218
|
const agentNode = opts.agentNode ?? "agent";
|
|
144
|
-
graph.addNode("atbash_guard", createGuardNode({ client }));
|
|
219
|
+
graph.addNode("atbash_guard", createGuardNode({ client, guardManager: guard }));
|
|
145
220
|
graph.addNode("atbash_audit", createAuditNode({ client }));
|
|
146
221
|
graph.addConditionalEdges("atbash_guard", (state) => {
|
|
147
222
|
return state.atbashVerdict === "ALLOW" ? toolsNode : agentNode;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atbash/atbash-langgraph",
|
|
3
|
-
"version": "0.0.5-dev.
|
|
3
|
+
"version": "0.0.5-dev.5",
|
|
4
4
|
"description": "Atbash safety guard and audit nodes for LangGraph workflows",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
"prepublishOnly": "npm run build"
|
|
38
38
|
},
|
|
39
39
|
"dependencies": {
|
|
40
|
-
"@atbash/sdk": "0.5
|
|
40
|
+
"@atbash/sdk": "0.10.5-dev.0",
|
|
41
41
|
"zod": "^3.25.76"
|
|
42
42
|
},
|
|
43
43
|
"peerDependencies": {
|