@verax-ai/body 0.1.0 → 0.1.2
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/LICENSE +192 -0
- package/README.md +60 -0
- package/dist/agents.d.ts +33 -0
- package/dist/agents.js +59 -0
- package/dist/approve-cli.js +27 -1
- package/dist/cli.js +5 -4
- package/dist/desktop.d.ts +23 -0
- package/dist/desktop.js +82 -30
- package/dist/doctor.js +87 -30
- package/dist/downstream.d.ts +28 -0
- package/dist/downstream.js +183 -0
- package/dist/inputs-read.d.ts +7 -0
- package/dist/inputs-read.js +47 -40
- package/dist/no-bypass-scan.js +7 -0
- package/dist/server.d.ts +183 -0
- package/dist/server.js +179 -37
- package/dist/tools/memory.d.ts +2 -0
- package/dist/tools/memory.js +7 -0
- package/dist/wiring.d.ts +10 -2
- package/dist/wiring.js +31 -4
- package/dist/witness.js +15 -13
- package/package.json +12 -1
package/dist/wiring.js
CHANGED
|
@@ -2,11 +2,11 @@ import { createProxy, FileLedger, loadPolicy, tenantKey, } from "@verax-ai/proxy
|
|
|
2
2
|
import { readFileSync } from "node:fs";
|
|
3
3
|
import { persistPolicySnapshot } from "./policy-store.js";
|
|
4
4
|
import { inputsPrincipal } from "./inputs-read.js";
|
|
5
|
-
import { memoryBelongsToOtherTenant, memoryGet, memoryPut, readMemoryMeta } from "./tools/memory.js";
|
|
5
|
+
import { memoryBelongsToOtherTenant, memoryExistsForTenant, memoryGet, memoryPut, readMemoryMeta, } from "./tools/memory.js";
|
|
6
6
|
import { auditExplain } from "./tools/audit.js";
|
|
7
7
|
import { messageRead, messageSend } from "./tools/message.js";
|
|
8
8
|
import { spendAuthorize } from "./tools/spend.js";
|
|
9
|
-
import { requestWitnessSign } from "./witness.js";
|
|
9
|
+
import { requestWitnessCheckpoint, requestWitnessSign } from "./witness.js";
|
|
10
10
|
export const TOOL_NAMES = [
|
|
11
11
|
"memory.get",
|
|
12
12
|
"memory.put",
|
|
@@ -17,11 +17,32 @@ export const TOOL_NAMES = [
|
|
|
17
17
|
];
|
|
18
18
|
/**
|
|
19
19
|
* Tool functions live in a Map that is not exported. The only way to
|
|
20
|
-
* reach them at runtime is `proxy.call` -> `inner`.
|
|
20
|
+
* reach them at runtime is `proxy.call` -> `inner`. Extra tools (a
|
|
21
|
+
* downstream prefix) enter that Map at construction; they still pass
|
|
22
|
+
* the gate.
|
|
21
23
|
*/
|
|
22
24
|
export function createBodyServices(opts) {
|
|
25
|
+
const extraNames = [];
|
|
26
|
+
const reserved = new Set(TOOL_NAMES);
|
|
27
|
+
for (const tool of opts.extraTools ?? []) {
|
|
28
|
+
if (reserved.has(tool.name) || extraNames.includes(tool.name)) {
|
|
29
|
+
throw new Error(`downstream-name-collision:${tool.name}`);
|
|
30
|
+
}
|
|
31
|
+
// Same shape as extraToolNameOk in downstream.ts (prefix.childName).
|
|
32
|
+
if (!/^[A-Za-z][A-Za-z0-9_-]{0,31}\.[A-Za-z][A-Za-z0-9._-]{0,63}$/.test(tool.name)) {
|
|
33
|
+
throw new Error(`downstream-name-invalid:${tool.name}`);
|
|
34
|
+
}
|
|
35
|
+
extraNames.push(tool.name);
|
|
36
|
+
}
|
|
23
37
|
const ledger = new FileLedger(opts.stateDir);
|
|
24
38
|
ledger.remoteWitness = (row, resultHash) => requestWitnessSign(opts.stateDir, row, resultHash);
|
|
39
|
+
ledger.onPieceClose = async (window) => {
|
|
40
|
+
await requestWitnessCheckpoint(opts.stateDir, {
|
|
41
|
+
epoch: 0,
|
|
42
|
+
startMs: window.startMs,
|
|
43
|
+
endMs: window.endMs,
|
|
44
|
+
});
|
|
45
|
+
};
|
|
25
46
|
const policyText = readFileSync(opts.policyFile, "utf8");
|
|
26
47
|
const policyDocument = JSON.parse(policyText);
|
|
27
48
|
const policy = loadPolicy(policyText);
|
|
@@ -49,6 +70,9 @@ export function createBodyServices(opts) {
|
|
|
49
70
|
registry.set("message.read", (call, principal) => messageRead(call, opts.stateDir, principal));
|
|
50
71
|
registry.set("message.send", (call, principal, ref) => messageSend(call, opts.stateDir, ref ?? "", principal));
|
|
51
72
|
registry.set("spend", (call, _principal, ref) => spendAuthorize(call, ref ?? ""));
|
|
73
|
+
for (const tool of opts.extraTools ?? []) {
|
|
74
|
+
registry.set(tool.name, tool.fn);
|
|
75
|
+
}
|
|
52
76
|
const inner = async (call, principal, ref) => {
|
|
53
77
|
const fn = registry.get(call.name);
|
|
54
78
|
if (!fn) {
|
|
@@ -73,6 +97,8 @@ export function createBodyServices(opts) {
|
|
|
73
97
|
const id = call.arguments.id;
|
|
74
98
|
if (typeof id !== "string")
|
|
75
99
|
return false;
|
|
100
|
+
if (memoryExistsForTenant(opts.stateDir, id, principal))
|
|
101
|
+
return false;
|
|
76
102
|
return memoryBelongsToOtherTenant(opts.stateDir, id, tenantKey(principal));
|
|
77
103
|
}
|
|
78
104
|
if (call.name === "audit.explain") {
|
|
@@ -93,9 +119,10 @@ export function createBodyServices(opts) {
|
|
|
93
119
|
return {
|
|
94
120
|
proxy,
|
|
95
121
|
ledger,
|
|
122
|
+
policy,
|
|
96
123
|
policyHash: policy.hash,
|
|
97
124
|
policyDocument,
|
|
98
|
-
listTools: () => TOOL_NAMES,
|
|
125
|
+
listTools: () => (extraNames.length === 0 ? TOOL_NAMES : [...TOOL_NAMES, ...extraNames]),
|
|
99
126
|
explainOpts,
|
|
100
127
|
};
|
|
101
128
|
}
|
package/dist/witness.js
CHANGED
|
@@ -5,7 +5,7 @@ import { join } from "node:path";
|
|
|
5
5
|
import { writeFileAtomic } from "./atomic-write.js";
|
|
6
6
|
import { buildCheckpointClaims, checkpointHash, signCheckpoint, totalsFromDecisionRecords, } from "@cedulon/checkpoint";
|
|
7
7
|
import { decisionRecordHash } from "@cedulon/core";
|
|
8
|
-
import { checkpointsPath, signEffectAttestation } from "@verax-ai/proxy";
|
|
8
|
+
import { checkpointsPath, listPieceFiles, signEffectAttestation } from "@verax-ai/proxy";
|
|
9
9
|
import { pidAlive } from "./unlock.js";
|
|
10
10
|
const WITNESS_CLASS = "same-org";
|
|
11
11
|
function listenPath(stateDir) {
|
|
@@ -104,21 +104,23 @@ function send(res, status, body) {
|
|
|
104
104
|
res.end(text);
|
|
105
105
|
}
|
|
106
106
|
function loadDecisions(stateDir) {
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
107
|
+
const out = [];
|
|
108
|
+
for (const piece of listPieceFiles(stateDir)) {
|
|
109
|
+
try {
|
|
110
|
+
const text = readFileSync(piece.decisions, "utf8");
|
|
111
|
+
for (const line of text.split("\n")) {
|
|
112
|
+
if (line === "")
|
|
113
|
+
continue;
|
|
114
|
+
out.push(JSON.parse(line));
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
catch (err) {
|
|
118
|
+
if (err.code === "ENOENT")
|
|
112
119
|
continue;
|
|
113
|
-
|
|
120
|
+
throw err;
|
|
114
121
|
}
|
|
115
|
-
return out;
|
|
116
|
-
}
|
|
117
|
-
catch (err) {
|
|
118
|
-
if (err.code === "ENOENT")
|
|
119
|
-
return [];
|
|
120
|
-
throw err;
|
|
121
122
|
}
|
|
123
|
+
return out;
|
|
122
124
|
}
|
|
123
125
|
function lastCheckpointHash(stateDir) {
|
|
124
126
|
try {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@verax-ai/body",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"engines": {
|
|
@@ -27,6 +27,17 @@
|
|
|
27
27
|
"jose": "^6.2.11"
|
|
28
28
|
},
|
|
29
29
|
"description": "VERAX body: an MCP server that decides, records and proves what an agent did.",
|
|
30
|
+
"homepage": "https://verax-ai.com",
|
|
31
|
+
"keywords": [
|
|
32
|
+
"verax",
|
|
33
|
+
"mcp",
|
|
34
|
+
"mcp-server",
|
|
35
|
+
"agent",
|
|
36
|
+
"policy",
|
|
37
|
+
"audit",
|
|
38
|
+
"ledger",
|
|
39
|
+
"approval"
|
|
40
|
+
],
|
|
30
41
|
"mcpName": "io.github.verax-ai/verax",
|
|
31
42
|
"scripts": {
|
|
32
43
|
"build": "tsc -p tsconfig.build.json",
|