Files
GlyphRunner System 1a0b45df9c Add LLMCompress subsystem - sandbox for symbolic compression of LLM behavior
New subsystem fully self-contained:

Components:
- LLMCompress/llm_adapter.py: LLMAdapter + LLMResponse (abstract over LLM backends)
- LLMCompress/compression_report.py: CompressionReport (symbolic analysis results)
- LLMCompress/llm_compressor.py: compress_interaction() and compress_session()
- LLMCompress/tests/test_llm_compress.py: 5 comprehensive tests

Integration:
- Uses GlyphOS Cognitive Kernel for symbolic analysis
- Integrates with GlyphOS Event System
- Emits cognition.started and cognition.completed events
- Supports in-memory GX execution via execute_symbolic()

Test Coverage:
- LLMCompress tests: 5/5 PASS
- All existing tests still pass (52/52)
- Total: 57 tests passing

Bug fixes in cognitive_kernel.py:
- Fixed execute_symbolic() method calls to use correct function signatures
- normalize_segments(manifest, segments, payload)
- map_lanes(segments)
- build_envelope(manifest, lanes, payload, context)
- execute_with_lain(envelope)

Constraints:
- No modifications to gx_compiler/*
- No modifications to glyphs/super_registry.py
- Self-contained subsystem with proper isolation
- Full backward compatibility maintained
2026-05-20 20:51:01 -04:00

93 lines
2.6 KiB
Python

"""LLM Adapter
Thin abstraction over a concrete LLM backend (local or remote).
"""
from __future__ import annotations
from dataclasses import dataclass
from typing import Any, Callable, Dict, Optional
@dataclass
class LLMResponse:
"""Container for a single LLM interaction."""
prompt: str
response: str
tokens_prompt: Optional[int] = None
tokens_response: Optional[int] = None
model_name: Optional[str] = None
metadata: Dict[str, Any] = None
def to_dict(self) -> Dict[str, Any]:
return {
"prompt": self.prompt,
"response": self.response,
"tokens_prompt": self.tokens_prompt,
"tokens_response": self.tokens_response,
"model_name": self.model_name,
"metadata": self.metadata or {},
}
class LLMAdapter:
"""Adapter around a concrete LLM backend.
backend: Callable that takes (prompt, **kwargs) and returns:
- str
- or dict with keys like:
- response
- tokens_prompt
- tokens_response
- model_name
"""
def __init__(
self,
backend: Callable[..., Any],
model_name: Optional[str] = None,
) -> None:
self._backend = backend
self._model_name = model_name or "unknown"
def run(self, prompt: str, **kwargs: Any) -> LLMResponse:
"""Run the underlying LLM on a prompt and normalize the result."""
raw = self._backend(prompt, **kwargs)
if isinstance(raw, str):
return LLMResponse(
prompt=prompt,
response=raw,
model_name=self._model_name,
metadata={},
)
if isinstance(raw, dict):
return LLMResponse(
prompt=prompt,
response=str(raw.get("response", "")),
tokens_prompt=raw.get("tokens_prompt"),
tokens_response=raw.get("tokens_response"),
model_name=raw.get("model_name", self._model_name),
metadata={
k: v
for k, v in raw.items()
if k
not in {
"response",
"tokens_prompt",
"tokens_response",
"model_name",
}
},
)
# Fallback: best-effort stringification
return LLMResponse(
prompt=prompt,
response=str(raw),
model_name=self._model_name,
metadata={"raw_type": type(raw).__name__},
)