diff --git a/harness-interface-spec.md b/harness-interface-spec.md new file mode 100644 index 0000000..11ed039 --- /dev/null +++ b/harness-interface-spec.md @@ -0,0 +1,134 @@ +# Harness Interface Specification + +## Standard Interface (All Harnesses Must Implement) + +```python +class Harness(ABC): + '''Abstract base for all agent harnesses''' + + @abstractmethod + def execute(self, prompt: str, context: Context) -> Response: + '''Execute a prompt and return response''' + pass + + @abstractmethod + def tool_call(self, tool: str, params: dict) -> Result: + '''Execute a specific tool''' + pass + + @abstractmethod + def session_save(self, session: Session) -> Checkpoint: + '''Save session state''' + pass + + @abstractmethod + def session_load(self, checkpoint: Checkpoint) -> Session: + '''Load session state''' + pass + + @property + @abstractmethod + def capabilities(self) -> List[str]: + '''Return list of supported capabilities''' + pass + + @property + @abstractmethod + def metrics(self) -> Metrics: + '''Return performance metrics''' + pass + +class ClawHarness(Harness): + '''Claw Code implementation''' + + def __init__(self, binary_path: str, model: str): + self.binary = binary_path + self.model = model + self.bridge = OllamaBridge() # or direct + + def execute(self, prompt, context): + # Claw-specific: fast, local, tool-heavy + return self.bridge.run(prompt, model=self.model) + +class HermesHarness(Harness): + '''Hermes Agent implementation''' + + def __init__(self, profile: str): + self.profile = profile + self.gateway = GatewayClient() + + def execute(self, prompt, context): + # Hermes-specific: complex workflows, skills + return self.gateway.chat(prompt, profile=self.profile) + +class OllamaHarness(Harness): + '''Ollama local implementation''' + + def __init__(self, model: str = "qwen2.5:1.5b"): + self.model = model + self.client = OllamaClient() + + def execute(self, prompt, context): + # Ollama-specific: fully local, offline + return self.client.generate(prompt, model=self.model) +``` + +## Usage (Wizard Code) + +```python +# Config-driven harness selection +config = load_profile("allegro") +harness = HarnessFactory.create(config.harness.default) + +# Same code, different runtime +response = harness.execute("Write Python hello world", context) + +# Fallback chain +for harness_name in config.harness.fallbacks: + try: + harness = HarnessFactory.create(harness_name) + return harness.execute(prompt, context) + except HarnessError: + continue +``` + +## Configuration Schema + +```yaml +# ~/.hermes/profiles/allegro/config.yaml +harness: + default: claw + fallbacks: + - name: hermes + condition: "complex_workflow" + - name: ollama + condition: "offline" + + claw: + binary: /opt/claw/claw-cli + model: claude-3-7-sonnet + bridge: ollama # or direct + + hermes: + profile: allegro + gateway: http://localhost:8644 + + ollama: + model: qwen2.5:1.5b + host: http://localhost:11434 + +tools: + - file + - terminal + - web + +selection_criteria: + speed: claw > ollama > hermes + capability: hermes > claw > ollama + offline: ollama only +``` + +--- + +*Design by Ezra* +*Implementation by Allegro* \ No newline at end of file