项目文件夹

文件
tjb-tech 5dd8b952ec Initial release: oh — OpenHarness: Open Agent Harness v0.1.0
A lightweight open-source Python implementation of the Agent Harness architecture.
44x lighter than Claude Code (11K vs 512K lines), 98% core tool coverage.

- 43 tools with Pydantic validation and parallel execution
- Skills system compatible with anthropics/skills (17+ tested)
- Plugin system compatible with claude-code/plugins (12+ tested)
- API retry with exponential backoff
- Multi-level permissions with path rules
- React/Ink TUI with "Oh my Harness!" branding
- 114 unit tests + 6 E2E test suites
- MIT License
2026-04-01 16:32:25 +00:00

73 行
2.2 KiB
Python

"""Tests for hooks execution."""
from __future__ import annotations
from pathlib import Path
import pytest
from openharness.api.client import ApiMessageCompleteEvent
from openharness.api.usage import UsageSnapshot
from openharness.engine.messages import ConversationMessage, TextBlock
from openharness.hooks import HookEvent, HookExecutionContext, HookExecutor
from openharness.hooks.loader import HookRegistry
from openharness.hooks.schemas import CommandHookDefinition, PromptHookDefinition
class FakeApiClient:
"""Minimal fake streaming client."""
def __init__(self, text: str) -> None:
self._text = text
async def stream_message(self, request):
del request
yield ApiMessageCompleteEvent(
message=ConversationMessage(role="assistant", content=[TextBlock(text=self._text)]),
usage=UsageSnapshot(input_tokens=1, output_tokens=1),
stop_reason=None,
)
@pytest.mark.asyncio
async def test_command_hook_executes(tmp_path: Path):
registry = HookRegistry()
registry.register(
HookEvent.SESSION_START,
CommandHookDefinition(command="printf 'booted'"),
)
executor = HookExecutor(
registry,
HookExecutionContext(cwd=tmp_path, api_client=FakeApiClient('{"ok": true}'), default_model="claude-test"),
)
result = await executor.execute(HookEvent.SESSION_START, {"event": "session_start"})
assert result.blocked is False
assert result.results[0].output == "booted"
@pytest.mark.asyncio
async def test_prompt_hook_can_block(tmp_path: Path):
registry = HookRegistry()
registry.register(
HookEvent.PRE_TOOL_USE,
PromptHookDefinition(prompt="Check tool call", matcher="bash"),
)
executor = HookExecutor(
registry,
HookExecutionContext(
cwd=tmp_path,
api_client=FakeApiClient('{"ok": false, "reason": "blocked by policy"}'),
default_model="claude-test",
),
)
result = await executor.execute(
HookEvent.PRE_TOOL_USE,
{"tool_name": "bash", "tool_input": {"command": "rm -rf ."}},
)
assert result.blocked is True
assert result.reason == "blocked by policy"