osmp 2.0.0__tar.gz

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.
osmp-2.0.0/PKG-INFO ADDED
@@ -0,0 +1,140 @@
1
+ Metadata-Version: 2.4
2
+ Name: osmp
3
+ Version: 2.0.0
4
+ Summary: OSMP -- Octid Semantic Mesh Protocol. Deterministic agentic instruction encoding.
5
+ Author-email: Clay Holberg <clay@octid.io>
6
+ Project-URL: Homepage, https://github.com/Octid-io/cloudless-sky
7
+ Project-URL: Documentation, https://github.com/Octid-io/cloudless-sky/blob/main/protocol/spec/OSMP-SPEC-v1.md
8
+ Project-URL: Repository, https://github.com/Octid-io/cloudless-sky
9
+ Project-URL: Issues, https://github.com/Octid-io/cloudless-sky/issues
10
+ Keywords: osmp,agentic,mesh,protocol,semantic,encoding,lora,ai
11
+ Classifier: Development Status :: 4 - Beta
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: License :: OSI Approved :: Apache Software License
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3.9
16
+ Classifier: Programming Language :: Python :: 3.10
17
+ Classifier: Programming Language :: Python :: 3.11
18
+ Classifier: Programming Language :: Python :: 3.12
19
+ Classifier: Topic :: Communications
20
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
21
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
22
+ Requires-Python: >=3.9
23
+ Description-Content-Type: text/markdown
24
+ Provides-Extra: dpack
25
+ Requires-Dist: zstandard>=0.21; extra == "dpack"
26
+
27
+ # OSMP Python SDK
28
+
29
+ Reference implementation of the Octid Semantic Mesh Protocol. Encodes, decodes, and validates agentic AI instructions using SAL (Semantic Assembly Language). 342 opcodes across 26 namespaces. Inference-free decode by table lookup.
30
+
31
+ ## Install
32
+
33
+ ```
34
+ pip install osmp
35
+ ```
36
+
37
+ Zero dependencies beyond Python standard library (optional `zstandard` for D:PACK).
38
+
39
+ ## Tier 1: Two Functions, Zero Setup
40
+
41
+ ```python
42
+ from osmp import encode, decode
43
+
44
+ sal = encode(["H:HR@NODE1>120", "H:CASREP", "M:EVA@*"])
45
+ # "H:HR@NODE1>120;H:CASREP;M:EVA@*"
46
+
47
+ text = decode("H:HR@NODE1>120;H:CASREP;M:EVA@*")
48
+ # "heart_rate at NODE1 priority 120; casualty_report; evacuation at broadcast"
49
+ ```
50
+
51
+ Three lines. No instantiation. Module-level singleton, cached on first call.
52
+
53
+ ### Additional Tier 1 Functions
54
+
55
+ ```python
56
+ from osmp import validate, lookup, byte_size
57
+
58
+ result = validate("R:MOV@BOT1⚠")
59
+ print(result.valid) # False -- ⚠ requires I:§ precondition
60
+
61
+ definition = lookup("R:WPT")
62
+ # "waypoint"
63
+
64
+ print(byte_size("H:HR@NODE1>120"))
65
+ # 15
66
+ ```
67
+
68
+ ## Tier 2: Class-Based Interface
69
+
70
+ For configuration beyond defaults (custom ASD floor, pre-loaded dependency rules, direct ASD access):
71
+
72
+ ```python
73
+ from osmp.core import OSMP
74
+
75
+ o = OSMP()
76
+ sal = o.encode(["H:HR@NODE1>120", "H:CASREP"])
77
+ text = o.decode(sal)
78
+ result = o.validate(sal)
79
+ definition = o.lookup("H", "HR")
80
+ ```
81
+
82
+ ## Tier 3: Full Protocol Access
83
+
84
+ Direct access to encoder, decoder, ASD, and all protocol internals:
85
+
86
+ ```python
87
+ from osmp.protocol import SALEncoder, SALDecoder, AdaptiveSharedDictionary, validate_composition
88
+
89
+ asd = AdaptiveSharedDictionary()
90
+ enc = SALEncoder(asd)
91
+ dec = SALDecoder(asd)
92
+
93
+ sal = enc.encode_frame("R", "MOV", target="BOT1", cc="↺")
94
+ result = dec.decode_frame(sal)
95
+ # result.namespace = "R"
96
+ # result.opcode = "MOV"
97
+ # result.opcode_meaning = "move"
98
+ # result.consequence_class_name = "REVERSIBLE"
99
+ ```
100
+
101
+ ## Composition Validation
102
+
103
+ Eight deterministic rules enforced before any instruction hits the wire:
104
+
105
+ 1. **Hallucination check** -- every opcode must exist in the ASD
106
+ 2. **Namespace-as-target** -- `@` must not be followed by `NS:OPCODE`
107
+ 3. **R namespace consequence class** -- mandatory except `R:ESTOP`
108
+ 4. **I:§ precondition** -- ⚠ and ⊘ require `I:§` in the chain
109
+ 5. **Byte check** -- SAL bytes must not exceed NL bytes (exception: R safety chains)
110
+ 6. **Slash rejection** -- `/` is not a SAL operator
111
+ 7. **Mixed-mode check** -- no natural language embedded in SAL frames
112
+ 8. **Regulatory dependency** -- REQUIRES rules from loaded MDR corpora
113
+
114
+ ## Domain Code Resolution
115
+
116
+ ```python
117
+ from osmp.protocol import BlockCompressor
118
+
119
+ bc = BlockCompressor()
120
+ bc.load("mdr/icd10cm/MDR-ICD10CM-FY2026-blk.dpack")
121
+ result = bc.resolve("J93.0")
122
+ # "Spontaneous tension pneumothorax"
123
+ ```
124
+
125
+ Three corpora bundled: ICD-10-CM (74,719 codes), ISO 20022 (47,835 codes), MITRE ATT&CK (1,661 codes).
126
+
127
+ ## MCP Server
128
+
129
+ The MCP server is a separate package that wraps this SDK:
130
+
131
+ ```
132
+ pip install osmp-mcp
133
+ osmp-mcp
134
+ ```
135
+
136
+ Nine tools for AI client integration. Connect from Claude Code (`claude mcp add osmp -- osmp-mcp`), Claude Desktop, Cursor, or any MCP-compatible client.
137
+
138
+ ## License
139
+
140
+ Apache 2.0. Patent pending. Filed March 17, 2026.
osmp-2.0.0/README.md ADDED
@@ -0,0 +1,114 @@
1
+ # OSMP Python SDK
2
+
3
+ Reference implementation of the Octid Semantic Mesh Protocol. Encodes, decodes, and validates agentic AI instructions using SAL (Semantic Assembly Language). 342 opcodes across 26 namespaces. Inference-free decode by table lookup.
4
+
5
+ ## Install
6
+
7
+ ```
8
+ pip install osmp
9
+ ```
10
+
11
+ Zero dependencies beyond Python standard library (optional `zstandard` for D:PACK).
12
+
13
+ ## Tier 1: Two Functions, Zero Setup
14
+
15
+ ```python
16
+ from osmp import encode, decode
17
+
18
+ sal = encode(["H:HR@NODE1>120", "H:CASREP", "M:EVA@*"])
19
+ # "H:HR@NODE1>120;H:CASREP;M:EVA@*"
20
+
21
+ text = decode("H:HR@NODE1>120;H:CASREP;M:EVA@*")
22
+ # "heart_rate at NODE1 priority 120; casualty_report; evacuation at broadcast"
23
+ ```
24
+
25
+ Three lines. No instantiation. Module-level singleton, cached on first call.
26
+
27
+ ### Additional Tier 1 Functions
28
+
29
+ ```python
30
+ from osmp import validate, lookup, byte_size
31
+
32
+ result = validate("R:MOV@BOT1⚠")
33
+ print(result.valid) # False -- ⚠ requires I:§ precondition
34
+
35
+ definition = lookup("R:WPT")
36
+ # "waypoint"
37
+
38
+ print(byte_size("H:HR@NODE1>120"))
39
+ # 15
40
+ ```
41
+
42
+ ## Tier 2: Class-Based Interface
43
+
44
+ For configuration beyond defaults (custom ASD floor, pre-loaded dependency rules, direct ASD access):
45
+
46
+ ```python
47
+ from osmp.core import OSMP
48
+
49
+ o = OSMP()
50
+ sal = o.encode(["H:HR@NODE1>120", "H:CASREP"])
51
+ text = o.decode(sal)
52
+ result = o.validate(sal)
53
+ definition = o.lookup("H", "HR")
54
+ ```
55
+
56
+ ## Tier 3: Full Protocol Access
57
+
58
+ Direct access to encoder, decoder, ASD, and all protocol internals:
59
+
60
+ ```python
61
+ from osmp.protocol import SALEncoder, SALDecoder, AdaptiveSharedDictionary, validate_composition
62
+
63
+ asd = AdaptiveSharedDictionary()
64
+ enc = SALEncoder(asd)
65
+ dec = SALDecoder(asd)
66
+
67
+ sal = enc.encode_frame("R", "MOV", target="BOT1", cc="↺")
68
+ result = dec.decode_frame(sal)
69
+ # result.namespace = "R"
70
+ # result.opcode = "MOV"
71
+ # result.opcode_meaning = "move"
72
+ # result.consequence_class_name = "REVERSIBLE"
73
+ ```
74
+
75
+ ## Composition Validation
76
+
77
+ Eight deterministic rules enforced before any instruction hits the wire:
78
+
79
+ 1. **Hallucination check** -- every opcode must exist in the ASD
80
+ 2. **Namespace-as-target** -- `@` must not be followed by `NS:OPCODE`
81
+ 3. **R namespace consequence class** -- mandatory except `R:ESTOP`
82
+ 4. **I:§ precondition** -- ⚠ and ⊘ require `I:§` in the chain
83
+ 5. **Byte check** -- SAL bytes must not exceed NL bytes (exception: R safety chains)
84
+ 6. **Slash rejection** -- `/` is not a SAL operator
85
+ 7. **Mixed-mode check** -- no natural language embedded in SAL frames
86
+ 8. **Regulatory dependency** -- REQUIRES rules from loaded MDR corpora
87
+
88
+ ## Domain Code Resolution
89
+
90
+ ```python
91
+ from osmp.protocol import BlockCompressor
92
+
93
+ bc = BlockCompressor()
94
+ bc.load("mdr/icd10cm/MDR-ICD10CM-FY2026-blk.dpack")
95
+ result = bc.resolve("J93.0")
96
+ # "Spontaneous tension pneumothorax"
97
+ ```
98
+
99
+ Three corpora bundled: ICD-10-CM (74,719 codes), ISO 20022 (47,835 codes), MITRE ATT&CK (1,661 codes).
100
+
101
+ ## MCP Server
102
+
103
+ The MCP server is a separate package that wraps this SDK:
104
+
105
+ ```
106
+ pip install osmp-mcp
107
+ osmp-mcp
108
+ ```
109
+
110
+ Nine tools for AI client integration. Connect from Claude Code (`claude mcp add osmp -- osmp-mcp`), Claude Desktop, Cursor, or any MCP-compatible client.
111
+
112
+ ## License
113
+
114
+ Apache 2.0. Patent pending. Filed March 17, 2026.
@@ -0,0 +1,146 @@
1
+ """
2
+ OSMP — Octid Semantic Mesh Protocol
3
+ Tier 1 API: Two functions. Zero setup.
4
+
5
+ from osmp import encode, decode
6
+
7
+ sal = encode(["H:HR@NODE1>120", "H:CASREP", "M:EVA@*"])
8
+ print(sal) # "H:HR@NODE1>120;H:CASREP;M:EVA@*"
9
+
10
+ text = decode("H:HR@NODE1>120;H:CASREP;M:EVA@*")
11
+ print(text) # "heart_rate at NODE1 priority 120; casualty_report; evacuation at broadcast"
12
+
13
+ Patent: OSMP-001-UTIL (pending) — inventor Clay Holberg
14
+ License: Apache 2.0
15
+ """
16
+
17
+ from __future__ import annotations
18
+
19
+ # Lazy-loaded singleton. The protocol module is heavy (~2700 lines).
20
+ # We don't import it until the first call, and we cache the instances.
21
+ _asd = None
22
+ _encoder = None
23
+ _decoder = None
24
+
25
+
26
+ def _init():
27
+ """Initialize singleton ASD, encoder, and decoder on first use."""
28
+ global _asd, _encoder, _decoder
29
+ if _asd is not None:
30
+ return
31
+
32
+ # Import from wherever the protocol internals live.
33
+ # This supports both the current osmp_mcp.osmp layout and
34
+ # the future osmp.protocol layout.
35
+ try:
36
+ from osmp.protocol import AdaptiveSharedDictionary, SALEncoder, SALDecoder
37
+ except ImportError:
38
+ try:
39
+ from osmp_mcp.osmp import AdaptiveSharedDictionary, SALEncoder, SALDecoder
40
+ except ImportError:
41
+ # Fallback: same package, different module name
42
+ from .osmp import AdaptiveSharedDictionary, SALEncoder, SALDecoder
43
+
44
+ _asd = AdaptiveSharedDictionary()
45
+ _encoder = SALEncoder(_asd)
46
+ _decoder = SALDecoder(_asd)
47
+
48
+
49
+ def encode(input_data) -> str:
50
+ """Encode to SAL.
51
+
52
+ Accepts:
53
+ list[str] — opcode strings, joined with ; (sequence operator)
54
+ str — if it looks like SAL (contains :), validates and returns as-is
55
+ if it looks like natural language, returns as NL_PASSTHROUGH
56
+
57
+ Returns:
58
+ SAL string ready for transmission.
59
+
60
+ Examples:
61
+ encode(["H:HR@NODE1>120", "H:CASREP", "M:EVA@*"])
62
+ → "H:HR@NODE1>120;H:CASREP;M:EVA@*"
63
+
64
+ encode("H:HR@NODE1>120;H:CASREP;M:EVA@*")
65
+ → "H:HR@NODE1>120;H:CASREP;M:EVA@*" (passthrough)
66
+ """
67
+ _init()
68
+
69
+ if isinstance(input_data, list):
70
+ return _encoder.encode_sequence(input_data)
71
+
72
+ if isinstance(input_data, str):
73
+ # If it contains namespace:opcode patterns, treat as pre-formatted SAL
74
+ if ":" in input_data and any(
75
+ c in input_data for c in "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
76
+ ):
77
+ # Looks like SAL already — return as-is
78
+ return input_data
79
+ # Natural language — return as NL passthrough
80
+ # (Future: NL-to-SAL conversion when composition engine is available)
81
+ return input_data
82
+
83
+ raise TypeError(
84
+ f"encode() accepts str or list[str], got {type(input_data).__name__}. "
85
+ f"Example: encode(['H:HR@NODE1>120', 'H:CASREP', 'M:EVA@*'])"
86
+ )
87
+
88
+
89
+ def decode(sal: str) -> str:
90
+ """Decode SAL to natural language description.
91
+
92
+ Accepts:
93
+ str — a SAL instruction string (single frame or ;-separated sequence)
94
+
95
+ Returns:
96
+ Human-readable natural language expansion of the SAL instruction,
97
+ resolved by ASD dictionary lookup. Zero inference.
98
+
99
+ Examples:
100
+ decode("H:HR@NODE1>120;H:CASREP;M:EVA@*")
101
+ → "H:heart_rate →NODE1>120; H:casualty_report; M:evacuation →*"
102
+ """
103
+ _init()
104
+ frames = [f.strip() for f in sal.split(";") if f.strip()]
105
+ if len(frames) <= 1:
106
+ return _decoder.decode_natural_language(sal)
107
+ return "; ".join(_decoder.decode_natural_language(f) for f in frames)
108
+
109
+
110
+ def validate(sal: str, nl: str = "", dependency_rules=None):
111
+ """Validate a composed SAL instruction against all eight rules.
112
+
113
+ Returns a CompositionResult with .valid (bool) and .issues (list).
114
+ """
115
+ _init()
116
+ try:
117
+ from osmp.protocol import validate_composition
118
+ except ImportError:
119
+ try:
120
+ from osmp_mcp.osmp import validate_composition
121
+ except ImportError:
122
+ from .osmp import validate_composition
123
+
124
+ return validate_composition(sal, nl, _asd, dependency_rules=dependency_rules)
125
+
126
+
127
+ def lookup(namespace_opcode: str) -> str | None:
128
+ """Look up an opcode definition in the ASD.
129
+
130
+ Accepts: "H:HR" or namespace="H", opcode="HR"
131
+ Returns: definition string or None if not found.
132
+ """
133
+ _init()
134
+ if ":" in namespace_opcode:
135
+ parts = namespace_opcode.split(":", 1)
136
+ return _asd.lookup(parts[0], parts[1])
137
+ return None
138
+
139
+
140
+ def byte_size(sal: str) -> int:
141
+ """Return UTF-8 byte count of a SAL string."""
142
+ return len(sal.encode("utf-8"))
143
+
144
+
145
+ # Version
146
+ __version__ = "2.0.0"
@@ -0,0 +1,124 @@
1
+ """
2
+ OSMP -- Octid Semantic Mesh Protocol
3
+ Tier 2 API: Class-based interface for advanced use.
4
+
5
+ from osmp.core import OSMP
6
+
7
+ o = OSMP()
8
+ sal = o.encode(["H:HR@NODE1>120", "H:CASREP", "M:EVA@*"])
9
+ text = o.decode(sal)
10
+ result = o.validate(sal)
11
+
12
+ For the two-function API, use Tier 1 instead:
13
+
14
+ from osmp import encode, decode
15
+
16
+ Patent: OSMP-001-UTIL (pending) -- inventor Clay Holberg
17
+ License: Apache 2.0
18
+ """
19
+
20
+ from __future__ import annotations
21
+
22
+ from pathlib import Path
23
+ from typing import TYPE_CHECKING
24
+
25
+ if TYPE_CHECKING:
26
+ from .protocol import (
27
+ AdaptiveSharedDictionary,
28
+ CompositionResult,
29
+ DependencyRule,
30
+ SALDecoder,
31
+ SALEncoder,
32
+ )
33
+
34
+
35
+ class OSMP:
36
+ """Full-featured OSMP codec with configurable ASD and dependency rules.
37
+
38
+ For zero-setup usage, prefer the module-level functions in ``osmp``.
39
+ This class exposes configuration points (custom ASD floor version,
40
+ pre-loaded dependency rules, direct ASD access) that the Tier 1
41
+ functions intentionally hide.
42
+ """
43
+
44
+ def __init__(
45
+ self,
46
+ floor_version: str | None = None,
47
+ dependency_rules: list[DependencyRule] | None = None,
48
+ ):
49
+ from .protocol import AdaptiveSharedDictionary, SALDecoder, SALEncoder
50
+
51
+ if floor_version is not None:
52
+ self._asd: AdaptiveSharedDictionary = AdaptiveSharedDictionary(floor_version)
53
+ else:
54
+ self._asd = AdaptiveSharedDictionary()
55
+
56
+ self._encoder: SALEncoder = SALEncoder(self._asd)
57
+ self._decoder: SALDecoder = SALDecoder(self._asd)
58
+ self._dependency_rules: list[DependencyRule] | None = dependency_rules
59
+
60
+ # -- Encoding --------------------------------------------------------
61
+
62
+ def encode(self, instructions: list[str]) -> str:
63
+ """Encode a list of opcode strings into a SAL instruction chain."""
64
+ return self._encoder.encode_sequence(instructions)
65
+
66
+ def encode_frame(
67
+ self,
68
+ namespace: str,
69
+ opcode: str,
70
+ target: str | None = None,
71
+ query_slot: str | None = None,
72
+ consequence_class: str | None = None,
73
+ ) -> str:
74
+ """Encode a single SAL frame from structured fields."""
75
+ return self._encoder.encode_frame(
76
+ namespace, opcode, target, query_slot,
77
+ consequence_class=consequence_class,
78
+ )
79
+
80
+ # -- Decoding --------------------------------------------------------
81
+
82
+ def decode(self, sal: str) -> str:
83
+ """Decode a SAL string to natural language. Handles sequences."""
84
+ frames = [f.strip() for f in sal.split(";") if f.strip()]
85
+ if len(frames) <= 1:
86
+ return self._decoder.decode_natural_language(sal)
87
+ return "; ".join(self._decoder.decode_natural_language(f) for f in frames)
88
+
89
+ def decode_frame(self, sal: str):
90
+ """Decode a single SAL frame to a DecodedInstruction."""
91
+ return self._decoder.decode_frame(sal)
92
+
93
+ # -- Validation ------------------------------------------------------
94
+
95
+ def validate(self, sal: str, nl: str = ""):
96
+ """Validate a SAL instruction against all eight composition rules."""
97
+ from .protocol import validate_composition
98
+ return validate_composition(
99
+ sal, nl, self._asd,
100
+ dependency_rules=self._dependency_rules,
101
+ )
102
+
103
+ # -- Lookup ----------------------------------------------------------
104
+
105
+ def lookup(self, namespace: str, opcode: str) -> str | None:
106
+ """Look up an opcode definition in the ASD."""
107
+ return self._asd.lookup(namespace, opcode)
108
+
109
+ # -- Direct access ---------------------------------------------------
110
+
111
+ @property
112
+ def asd(self):
113
+ """Direct access to the AdaptiveSharedDictionary instance."""
114
+ return self._asd
115
+
116
+ @property
117
+ def encoder(self):
118
+ """Direct access to the SALEncoder instance."""
119
+ return self._encoder
120
+
121
+ @property
122
+ def decoder(self):
123
+ """Direct access to the SALDecoder instance."""
124
+ return self._decoder