Conversation
Greptile SummaryThis PR implements PR 2 from RFC 005's implementation plan: the foundation type system for agentic harness integration. It introduces Pydantic models ( The changes are additive and self-contained — no existing code is modified. The types align well with the project's existing Pydantic-based type system and follow the same
Alignment Review ReportAutomated Checks
Tier 1: Fixes Required
Tier 2: Alignment DiscussionNone identified — the types are purely additive, respect the dual API boundary (harness messages go through Confidence Score: 4/5
Important Files Changed
Class DiagramclassDiagram
class Action {
+Dict metadata
}
class HarnessAction {
+Literal type = "harness_message"
+str message
}
Action <|-- HarnessAction
class HarnessTransport {
<<enum>>
STDIO = "stdio"
STREAMABLE_HTTP = "http"
MCP = "mcp"
}
class HarnessEventType {
<<enum>>
LLM_REQUEST
LLM_RESPONSE
LLM_CHUNK
TOOL_CALL
TOOL_RESULT
TEXT_OUTPUT
ERROR
TURN_COMPLETE
}
class HarnessEvent {
+HarnessEventType type
+float timestamp
+Dict data
}
HarnessEvent --> HarnessEventType
class HarnessResponse {
+str response
+List~HarnessEvent~ events
+bool done
}
HarnessResponse --> HarnessEvent
class HarnessConfig {
+str name
+List~str~ command
+str working_directory
+Dict env_vars
+HarnessTransport transport
+Optional~str~ mcp_config_path
+float startup_timeout_s
+float session_timeout_s
+Optional~str~ model
+Optional~str~ api_key_env_var
}
HarnessConfig --> HarnessTransport
class HarnessAdapter {
<<abstract>>
+HarnessConfig config
+start(working_directory) None
+stop() None
+inject_tools(tools) None
+send_message(message) HarnessResponse
+send_message_streaming(message) AsyncIterator~HarnessEvent~
+is_alive() bool
}
HarnessAdapter --> HarnessConfig
HarnessAdapter --> HarnessResponse
HarnessAdapter --> HarnessEvent
class Tool {
+str name
+str description
+Dict input_schema
}
class resolve_tool_conflicts {
<<function>>
+resolve(env_tools, harness_builtin_tools) List~Tool~
}
resolve_tool_conflicts --> Tool
Last reviewed commit: 0c5d074 |
Introduces the core type system for agentic harness integration: - HarnessConfig: Pydantic model for harness process configuration - HarnessTransport: Enum for communication transport (stdio, http, mcp) - HarnessAdapter: ABC for harness-specific lifecycle management - HarnessEvent/HarnessEventType: Standard event schema for trajectories - HarnessResponse: Complete turn response with events and done signal - HarnessAction: Action type for sending messages to harnesses - resolve_tool_conflicts(): Utility for tool name collision handling 43 tests covering all types, serialization, validation, and edge cases. Part of #385
- Add List[Tool] type parameter to HarnessAdapter.inject_tools() - Add gt=0 validation to timeout fields in HarnessConfig
a993c0c to
2408704
Compare
* Add HarnessEnvironment with multi-turn support (RFC 005) Implements HarnessEnvironment, which wraps an external agentic harness with OpenEnv's Gym-style API: - reset() stops any running harness, injects MCP tools, starts fresh - step(HarnessAction) sends one conversational turn to the harness - Harness maintains conversation context across step() calls - done signal propagated from harness to observation - Trajectory accumulated across turns, accessible via .trajectory - close() cleans up harness process 26 tests covering reset, multi-turn step, trajectory accumulation, state management, close behavior, and MCP tool injection. Part of #385 * Address review feedback: fix async context manager and logging - Fix broken async context manager in _get_mcp_tool_definitions: use single async function with 'async with' instead of separate run_async_safely calls for __aenter__/__aexit__ - Add warning log on MCP tool extraction failure instead of silently swallowing exceptions * [3/3] Add OpenClaw adapter (RFC 005) (#391) * Add OpenClaw adapter implementation (RFC 005) Concrete HarnessAdapter for the OpenClaw agentic platform: - Process lifecycle: start/stop via asyncio subprocess - MCP tool injection: writes mcpServers config to openclaw.json, merges with existing config entries - Communication: JSON-line protocol over stdin/stdout - Event extraction: parses tool_calls from responses into HarnessEvents - Streaming: yields events from turn response - Error handling: timeout detection, plain-text fallback 18 tests covering imports, config injection, process lifecycle, message sending with JSON/plain-text responses, tool call extraction, streaming, and HarnessEnvironment integration. Part of #385 * Address review feedback: move import os to top of file * Fix env variable bug and add missing test coverage - Fix critical bug: env vars now merge with parent env (os.environ) instead of replacing it, preserving PATH, PYTHONPATH, etc. - When no env_vars or api_key configured, pass None to inherit parent - Add test for parent env inheritance with custom env vars - Add test for None env when no overrides configured - Add test for kill path when terminate times out - Add test for send_message timeout handling - Add test for corrupted config file handling - Add subprocess pipe parameter assertions to start test
Summary
Stacked on #387 (RFC 005).
Introduces the core type system for agentic harness integration:
HarnessConfig- Pydantic model for configuring harness processesHarnessTransport- Enum: stdio, streamable HTTP, MCPHarnessAdapter- ABC for harness-specific lifecycle (start, stop, inject_tools, send_message, send_message_streaming)HarnessEvent/HarnessEventType- Standard event schema for turn trajectories (8 event types)HarnessResponse- Complete turn response with events list and done signalHarnessAction- Action type extendingActionfor sending messages to harnessesresolve_tool_conflicts()- Utility for detecting and resolving tool name collisions viaenv_prefixingTest plan
Part of #385