@crvouga/mockingbird-service-hermes 0.1.0

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.
@@ -0,0 +1,71 @@
1
+ """Exact-source loading without importing gateway startup or inference."""
2
+ import ast
3
+ import hashlib
4
+ import json
5
+ import sys
6
+ import types
7
+ from pathlib import Path
8
+
9
+ LOCK = json.loads(Path(__file__).with_name("source-lock.json").read_text())
10
+
11
+
12
+ def verify(directory):
13
+ directory = Path(directory)
14
+ for name, expected in LOCK["sources"].items():
15
+ data = (directory / name).read_bytes()
16
+ if hashlib.sha256(data).hexdigest() != expected["sha256"]:
17
+ raise ValueError(f"Pinned source hash mismatch: {name}")
18
+ return LOCK
19
+
20
+
21
+ def definitions(path, roots, namespace):
22
+ """Compile original AST nodes and their local definition dependencies.
23
+
24
+ Imports are explicitly supplied by the harness. No function body is rewritten;
25
+ future annotations avoid loading unrelated annotation-only dependencies.
26
+ Return selected names so provenance can disclose the exact loading boundary.
27
+ """
28
+ tree = ast.parse(Path(path).read_text(), filename=str(path))
29
+ definitions_by_name = {}
30
+ for node in tree.body:
31
+ candidates = node.body if isinstance(node, ast.ClassDef) and node.name == "APIServerAdapter" else [node]
32
+ for candidate in candidates:
33
+ if isinstance(candidate, (ast.FunctionDef, ast.AsyncFunctionDef, ast.ClassDef)):
34
+ definitions_by_name[candidate.name] = candidate
35
+ elif isinstance(candidate, (ast.Assign, ast.AnnAssign)):
36
+ targets = candidate.targets if isinstance(candidate, ast.Assign) else [candidate.target]
37
+ for target in targets:
38
+ if isinstance(target, ast.Name):
39
+ definitions_by_name[target.id] = candidate
40
+ selected = set()
41
+ pending = list(roots)
42
+ while pending:
43
+ name = pending.pop()
44
+ if name in selected or name in namespace:
45
+ continue
46
+ node = definitions_by_name.get(name)
47
+ if node is None:
48
+ if name in roots:
49
+ raise ValueError(f"Missing pinned definition: {name}")
50
+ continue
51
+ selected.add(name)
52
+ pending.extend(n.id for n in ast.walk(node) if isinstance(n, ast.Name) and isinstance(n.ctx, ast.Load))
53
+ nodes = {id(definitions_by_name[name]): definitions_by_name[name] for name in selected}
54
+ module = ast.Module(body=[ast.ImportFrom(module="__future__", names=[ast.alias(name="annotations")], level=0), *sorted(nodes.values(), key=lambda node: node.lineno)], type_ignores=[])
55
+ ast.fix_missing_locations(module)
56
+ exec(compile(module, str(path), "exec"), namespace)
57
+ return sorted(selected)
58
+
59
+
60
+ def load_module(path, name):
61
+ module = types.ModuleType(name)
62
+ module.__file__ = str(path)
63
+ sys.modules[name] = module
64
+ exec(compile(Path(path).read_text(), str(path), "exec"), module.__dict__)
65
+ return module
66
+
67
+
68
+ if __name__ == "__main__":
69
+ import sys
70
+ manifest = verify(sys.argv[1])
71
+ print(json.dumps({"commit": manifest["commit"], "verified_files": len(manifest["sources"])}))
@@ -0,0 +1,50 @@
1
+ """Dependency-free checks: never start upstream code, services or databases."""
2
+ import unittest
3
+ from pathlib import Path
4
+ from unittest.mock import patch
5
+ from sources import definitions, verify
6
+
7
+
8
+ class SourceLoadingTests(unittest.TestCase):
9
+ def test_transitive_definitions_preserve_behavior_without_running_startup(self):
10
+ fixture = '''
11
+ LIMIT = 3
12
+ raise RuntimeError("unrelated gateway startup must not execute")
13
+ def helper(value):
14
+ return value + LIMIT
15
+ def handler(value):
16
+ return helper(value) if value else "invalid"
17
+ '''
18
+ namespace = {}
19
+ with patch.object(Path, "read_text", return_value=fixture):
20
+ names = definitions("fixture.py", ["handler"], namespace)
21
+ self.assertEqual(names, ["LIMIT", "handler", "helper"])
22
+ self.assertEqual(namespace["handler"](4), 7)
23
+ self.assertEqual(namespace["handler"](0), "invalid")
24
+
25
+ def test_missing_required_definition_fails_closed(self):
26
+ with patch.object(Path, "read_text", return_value="def different(): pass"):
27
+ with self.assertRaisesRegex(ValueError, "Missing pinned definition: handler"):
28
+ definitions("fixture.py", ["handler"], {})
29
+
30
+ def test_source_tampering_fails_before_execution(self):
31
+ with patch.object(Path, "read_bytes", return_value=b"changed source"):
32
+ with self.assertRaisesRegex(ValueError, "Pinned source hash mismatch"):
33
+ verify("unread-fixture")
34
+
35
+ def test_selected_adapter_method_keeps_staticmethod_binding(self):
36
+ fixture = '''
37
+ class APIServerAdapter:
38
+ @staticmethod
39
+ def header(request):
40
+ return request["value"]
41
+ '''
42
+ namespace = {}
43
+ with patch.object(Path, "read_text", return_value=fixture):
44
+ definitions("fixture.py", ["header"], namespace)
45
+ adapter = type("Adapter", (), {"header": namespace["header"]})
46
+ self.assertEqual(adapter().header({"value": "synthetic"}), "synthetic")
47
+
48
+
49
+ if __name__ == "__main__":
50
+ unittest.main()
package/package.json ADDED
@@ -0,0 +1,117 @@
1
+ {
2
+ "name": "@crvouga/mockingbird-service-hermes",
3
+ "version": "0.1.0",
4
+ "description": "Hermes peer-run API mock with portable scripted lifecycle controls.",
5
+ "license": "MIT",
6
+ "type": "module",
7
+ "sideEffects": false,
8
+ "files": [
9
+ "dist",
10
+ "README.md",
11
+ "CHANGELOG.md",
12
+ "API_EVIDENCE.md",
13
+ "SUPPORT.md",
14
+ "oracle",
15
+ "evidence",
16
+ "DISCOVERY.md",
17
+ "openapi.yaml"
18
+ ],
19
+ "main": "./dist/index.js",
20
+ "types": "./dist/index.d.ts",
21
+ "exports": {
22
+ ".": {
23
+ "types": "./dist/index.d.ts",
24
+ "default": "./dist/index.js"
25
+ },
26
+ "./server": {
27
+ "types": "./dist/server.d.ts",
28
+ "default": "./dist/server.js"
29
+ }
30
+ },
31
+ "bin": {
32
+ "mockingbird-hermes": "./dist/cli.js"
33
+ },
34
+ "publishConfig": {
35
+ "access": "public",
36
+ "provenance": true
37
+ },
38
+ "repository": {
39
+ "type": "git",
40
+ "url": "git+https://github.com/crvouga/mockingbird.git",
41
+ "directory": "packages/service/hermes"
42
+ },
43
+ "homepage": "https://github.com/crvouga/mockingbird/tree/main/packages/service/hermes#readme",
44
+ "keywords": [
45
+ "mockingbird",
46
+ "service",
47
+ "hermes",
48
+ "peer-runs"
49
+ ],
50
+ "mockingbird": {
51
+ "runtime": "portable",
52
+ "entries": {
53
+ "server": "node",
54
+ "cli": "node"
55
+ },
56
+ "layer": "service",
57
+ "category": "infrastructure",
58
+ "displayName": "Hermes Agent",
59
+ "vendor": {
60
+ "website": "https://hermes-agent.nousresearch.com",
61
+ "docs": "https://hermes-agent.nousresearch.com/docs/user-guide/features/api-server/",
62
+ "description": "Hermes Agent exposes asynchronous public peer-run APIs."
63
+ },
64
+ "status": "wip",
65
+ "playground": {
66
+ "operation": "RunCreate"
67
+ },
68
+ "parity": "Pinned Hermes run lifecycle and recovery",
69
+ "discovery": {
70
+ "guide": "DISCOVERY.md",
71
+ "behavior": "README.md",
72
+ "capabilities": "SUPPORT.md",
73
+ "contract": "openapi.yaml",
74
+ "types": "dist/index.d.ts",
75
+ "oracle": {
76
+ "kind": "Live vendor API or sandbox",
77
+ "command": "bun run parity:service -- hermes",
78
+ "note": "Run from a Mockingbird checkout; credentials come only from .env.local or GitHub Actions secrets. Missing credentials exit 2."
79
+ },
80
+ "introspection": [
81
+ "GET /__admin/health",
82
+ "GET /__admin",
83
+ "GET /__admin/state",
84
+ "GET /__admin/requests",
85
+ "GET /__admin/metrics",
86
+ "GET /__admin/faults/presets",
87
+ "GET /__admin/ui"
88
+ ],
89
+ "reporting": "https://github.com/crvouga/mockingbird/blob/main/docs/REPORTING_ISSUES.md"
90
+ }
91
+ },
92
+ "scripts": {
93
+ "generate": "bun ../../openapi/codegen/dist/cli.js",
94
+ "generate:check": "bun ../../openapi/codegen/dist/cli.js --check",
95
+ "openapi:check": "bun ../../openapi/codegen/dist/cli.js --validate",
96
+ "build": "bun ../../../scripts/bundle-service.ts",
97
+ "typecheck": "tsc -p tsconfig.json --noEmit",
98
+ "lint": "biome check .",
99
+ "test": "bun test",
100
+ "portability": "bun ../../../scripts/portability.ts",
101
+ "pack:check": "bun ../../../scripts/pack-check.ts"
102
+ },
103
+ "dependencies": {
104
+ "@crvouga/mockingbird-service-sqlite": "2.1.1",
105
+ "hono": "4.11.9"
106
+ },
107
+ "devDependencies": {
108
+ "@crvouga/mockingbird-parity": "0.0.0-development",
109
+ "@crvouga/mockingbird-testing": "0.1.0",
110
+ "@crvouga/mockingbird-openapi-codegen": "0.1.0",
111
+ "@crvouga/mockingbird-core": "0.0.0-development",
112
+ "@crvouga/mockingbird-sqlite": "0.0.0-development",
113
+ "@crvouga/mockingbird-openapi": "0.0.0-development",
114
+ "@crvouga/mockingbird-service": "0.0.0-development",
115
+ "@crvouga/mockingbird-adapter-node": "0.0.0-development"
116
+ }
117
+ }