@atbash/atbash-langgraph 0.0.5-dev.2 → 0.0.5-dev.4

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 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, AgentAuth, AtbashOptions } 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,21 +16,39 @@ 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
 
22
23
  interface AuditNodeOptions {
23
- agent: AgentAuth;
24
- clientOpts?: AtbashOptions;
24
+ client: Atbash;
25
25
  }
26
26
  declare function createAuditNode(opts: AuditNodeOptions): (state: AtbashState) => Promise<Partial<AtbashState>>;
27
27
 
28
28
  interface AtbashSafetyOptions {
29
- agent?: AgentAuth;
30
29
  privkey?: string;
31
30
  endpoint?: string;
32
31
  toolsNode?: string;
33
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;
34
52
  }
35
53
  declare function addAtbashSafety(builder: StateGraph<AtbashState>, opts: AtbashSafetyOptions): StateGraph<_langchain_langgraph.StateType<{
36
54
  atbashVerdict: _langchain_langgraph.BaseChannel<string | null, string | _langchain_langgraph.OverwriteValue<string | null> | null, unknown>;
@@ -52,7 +70,7 @@ declare function addAtbashSafety(builder: StateGraph<AtbashState>, opts: AtbashS
52
70
  messages: _langchain_langgraph.BaseChannel<_langchain_core_messages.BaseMessage<_langchain_core_messages.MessageStructure<_langchain_core_messages.MessageToolSet>, _langchain_core_messages.MessageType>[], _langchain_langgraph.OverwriteValue<_langchain_core_messages.BaseMessage<_langchain_core_messages.MessageStructure<_langchain_core_messages.MessageToolSet>, _langchain_core_messages.MessageType>[]> | _langchain_langgraph.Messages, unknown>;
53
71
  }>>, "__start__", _langchain_langgraph.StateDefinition, _langchain_langgraph.StateDefinition, _langchain_langgraph.StateDefinition, unknown, unknown, unknown>;
54
72
 
55
- declare function createJudgeTool(agent: AgentAuth, endpoint?: string): _langchain_core_tools.DynamicStructuredTool<z.ZodObject<{
73
+ declare function createJudgeTool(client: Atbash): _langchain_core_tools.DynamicStructuredTool<z.ZodObject<{
56
74
  action: z.ZodString;
57
75
  context: z.ZodString;
58
76
  }, "strip", z.ZodTypeAny, {
package/dist/index.js CHANGED
@@ -33,11 +33,63 @@ function createGuardNode(opts) {
33
33
  atbashReason: "No tool calls detected"
34
34
  };
35
35
  }
36
- const actionText = toolCalls.map((toolCall) => `${toolCall.name}(${JSON.stringify(toolCall.args)})`).join("; ");
36
+ const memoryHandledIds = /* @__PURE__ */ new Set();
37
+ if (opts.guardManager) {
38
+ for (const tc of toolCalls) {
39
+ let memDecision;
40
+ try {
41
+ memDecision = await opts.guardManager.handleBeforeToolCall(
42
+ { toolName: tc.name, args: tc.args },
43
+ {}
44
+ );
45
+ } catch (err) {
46
+ const reason = err instanceof Error ? err.message : String(err);
47
+ return {
48
+ messages: toolCalls.map(
49
+ (toolCall) => new ToolMessage({
50
+ tool_call_id: toolCall.id,
51
+ content: toolCall.id === tc.id ? `Memory guard error: ${reason}` : "Blocked \u2014 memory safety check failed for another tool call"
52
+ })
53
+ ),
54
+ atbashVerdict: "BLOCK",
55
+ atbashReason: `Memory guard error: ${reason}`,
56
+ atbashToolCallId: null,
57
+ atbashConfidence: null
58
+ };
59
+ }
60
+ if (memDecision !== null) {
61
+ if (memDecision.block) {
62
+ return {
63
+ messages: toolCalls.map(
64
+ (toolCall) => new ToolMessage({
65
+ tool_call_id: toolCall.id,
66
+ content: toolCall.id === tc.id ? `Memory write blocked by Atbash: ${memDecision.blockReason ?? ""}` : "Blocked \u2014 another tool call was blocked by memory safety"
67
+ })
68
+ ),
69
+ atbashVerdict: "BLOCK",
70
+ atbashReason: memDecision.blockReason ?? "memory write blocked",
71
+ atbashToolCallId: null,
72
+ atbashConfidence: null
73
+ };
74
+ }
75
+ memoryHandledIds.add(tc.id);
76
+ }
77
+ }
78
+ }
79
+ const auditCalls = toolCalls.filter((tc) => !memoryHandledIds.has(tc.id));
80
+ if (auditCalls.length === 0) {
81
+ return {
82
+ atbashVerdict: "ALLOW",
83
+ atbashReason: "Memory operations validated by guard",
84
+ atbashToolCallId: null,
85
+ atbashConfidence: null
86
+ };
87
+ }
88
+ const actionText = auditCalls.map((toolCall) => `${toolCall.name}(${JSON.stringify(toolCall.args)})`).join("; ");
37
89
  try {
38
90
  const decision = await opts.client.auditToolCall({
39
- toolName: toolCalls.map((t) => t.name).join(",") || "langgraph_batch",
40
- args: toolCalls,
91
+ toolName: auditCalls.map((t) => t.name).join(",") || "langgraph_batch",
92
+ args: auditCalls,
41
93
  context: `LangGraph agent attempting: ${actionText}`
42
94
  });
43
95
  if (decision.verdict === "BLOCK" || decision.verdict === "ERROR") {
@@ -101,9 +153,6 @@ function createGuardNode(opts) {
101
153
  };
102
154
  }
103
155
 
104
- // src/nodes/auditNode.ts
105
- import { Atbash } from "@atbash/sdk";
106
-
107
156
  // src/utils.ts
108
157
  function truncateText(value, max = 500) {
109
158
  return value.length <= max ? value : `${value.slice(0, max - 3)}...`;
@@ -111,12 +160,12 @@ function truncateText(value, max = 500) {
111
160
 
112
161
  // src/nodes/auditNode.ts
113
162
  function createAuditNode(opts) {
163
+ const { client } = opts;
114
164
  return async (state) => {
115
165
  const lastMessage = state.messages[state.messages.length - 1];
116
166
  const content = typeof lastMessage?.content === "string" ? lastMessage.content : JSON.stringify(lastMessage?.content ?? "");
117
167
  try {
118
- const client = new Atbash(opts.agent.privkey, opts.clientOpts);
119
- await client.judgeAction(
168
+ await client.logToolCall(
120
169
  truncateText(content, 500),
121
170
  "LangGraph tool execution completed"
122
171
  );
@@ -128,25 +177,45 @@ function createAuditNode(opts) {
128
177
 
129
178
  // src/builder.ts
130
179
  import {
131
- Atbash as Atbash2,
132
- loadAgent,
180
+ Atbash,
181
+ createMemoryGuardManager,
133
182
  setupTelemetry,
134
183
  shutdownTelemetry
135
184
  } from "@atbash/sdk";
185
+ import { homedir } from "os";
186
+ function expandHome(p) {
187
+ return p.replace(/^~(?=\/|$)/, homedir());
188
+ }
136
189
  function addAtbashSafety(builder, opts) {
137
190
  setupTelemetry({ enabled: true, source: "plugin:langgraph" });
138
191
  process.once("beforeExit", () => shutdownTelemetry());
139
192
  process.once("SIGINT", () => shutdownTelemetry().finally(() => process.exit(0)));
140
193
  process.once("SIGTERM", () => shutdownTelemetry().finally(() => process.exit(0)));
141
- const privkey = opts.privkey ?? process.env.ATBASH_AGENT_PRIVKEY;
142
- const agent = opts.agent ?? loadAgent(privkey ?? "");
143
- const clientOpts = opts.endpoint ? { endpoint: opts.endpoint } : void 0;
144
- const client = new Atbash2(agent.privkey, clientOpts);
194
+ const privkey = opts.privkey ?? process.env.ATBASH_AGENT_PRIVKEY ?? "";
195
+ const clientOpts = {};
196
+ if (opts.endpoint) clientOpts.endpoint = opts.endpoint;
197
+ const client = new Atbash(privkey, clientOpts);
198
+ const guard = createMemoryGuardManager({
199
+ auth: client.auth,
200
+ workspaceDir: opts.workspaceDir ? expandHome(opts.workspaceDir) : process.cwd(),
201
+ ...opts.memoryFilePath ? { memoryFilePath: expandHome(opts.memoryFilePath) } : {},
202
+ ...opts.memorySyncTTLMs !== void 0 ? { ttlMs: opts.memorySyncTTLMs } : {},
203
+ ...opts.memoryRollbackMinScore !== void 0 ? { rollbackMinScore: opts.memoryRollbackMinScore } : {},
204
+ ...opts.memoryPathPatterns ? { memoryPathPatterns: opts.memoryPathPatterns } : {},
205
+ ...opts.judgeEndpoint ? { judgeEndpoint: opts.judgeEndpoint } : {},
206
+ ...opts.judgeVerifyPubKey ? { judgeVerifyPubKey: opts.judgeVerifyPubKey } : {},
207
+ ...opts.orgName ? { orgName: opts.orgName } : {},
208
+ enforce: opts.enforce ?? true,
209
+ debug: opts.debug ?? false
210
+ });
211
+ guard.runBootProbe().catch((err) => {
212
+ console.warn("[atbash] boot probe failed:", err instanceof Error ? err.message : String(err));
213
+ });
145
214
  const graph = builder;
146
215
  const toolsNode = opts.toolsNode ?? "tools";
147
216
  const agentNode = opts.agentNode ?? "agent";
148
- graph.addNode("atbash_guard", createGuardNode({ client }));
149
- graph.addNode("atbash_audit", createAuditNode({ agent, clientOpts }));
217
+ graph.addNode("atbash_guard", createGuardNode({ client, guardManager: guard }));
218
+ graph.addNode("atbash_audit", createAuditNode({ client }));
150
219
  graph.addConditionalEdges("atbash_guard", (state) => {
151
220
  return state.atbashVerdict === "ALLOW" ? toolsNode : agentNode;
152
221
  });
@@ -156,19 +225,21 @@ function addAtbashSafety(builder, opts) {
156
225
  }
157
226
 
158
227
  // src/tools/judgeTool.ts
159
- import { Atbash as Atbash3 } from "@atbash/sdk";
160
228
  import { tool } from "@langchain/core/tools";
161
229
  import { z } from "zod";
162
- function createJudgeTool(agent, endpoint) {
230
+ function createJudgeTool(client) {
163
231
  return tool(
164
232
  async ({ action, context }) => {
165
- const client = new Atbash3(agent.privkey, endpoint ? { endpoint } : void 0);
166
- const result = await client.judgeAction(action, context);
233
+ const decision = await client.auditToolCall({
234
+ toolName: "atbash_safety_check",
235
+ args: { action },
236
+ context
237
+ });
167
238
  return JSON.stringify({
168
- verdict: result.verdict,
169
- reason: result.reason,
170
- confidence: result.confidence,
171
- tool_call_id: result.toolCallId
239
+ verdict: decision.verdict,
240
+ allow: decision.allow,
241
+ reason: decision.reason,
242
+ tool_call_id: decision.toolCallId
172
243
  });
173
244
  },
174
245
  {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atbash/atbash-langgraph",
3
- "version": "0.0.5-dev.2",
3
+ "version": "0.0.5-dev.4",
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.3-dev.0",
40
+ "@atbash/sdk": "0.10.5-dev.0",
41
41
  "zod": "^3.25.76"
42
42
  },
43
43
  "peerDependencies": {