agent-harness 0.11.1 → 0.11.3
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.
- checksums.yaml +4 -4
- data/.release-please-manifest.json +1 -1
- data/CHANGELOG.md +14 -0
- data/lib/agent_harness/configuration.rb +68 -1
- data/lib/agent_harness/errors.rb +11 -0
- data/lib/agent_harness/extensions.rb +644 -0
- data/lib/agent_harness/mcp_config_loader.rb +62 -0
- data/lib/agent_harness/mcp_config_translator.rb +85 -0
- data/lib/agent_harness/mcp_server.rb +40 -14
- data/lib/agent_harness/providers/anthropic.rb +3 -79
- data/lib/agent_harness/providers/base.rb +212 -9
- data/lib/agent_harness/providers/codex.rb +32 -1
- data/lib/agent_harness/providers/mcp_config_file_support.rb +76 -0
- data/lib/agent_harness/version.rb +1 -1
- data/lib/agent_harness.rb +45 -0
- metadata +5 -1
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module AgentHarness
|
|
4
|
+
module Providers
|
|
5
|
+
# Shared concern for writing and cleaning up MCP configuration tempfiles.
|
|
6
|
+
#
|
|
7
|
+
# Include this module in any provider that needs to write MCP config files
|
|
8
|
+
# for CLI processes. The including class must define an +mcp_provider_key+
|
|
9
|
+
# method that returns the symbol passed to +McpConfigTranslator.for_provider+.
|
|
10
|
+
module McpConfigFileSupport
|
|
11
|
+
def write_mcp_config_file(mcp_servers, working_dir: nil)
|
|
12
|
+
require "tempfile"
|
|
13
|
+
require "tmpdir"
|
|
14
|
+
require "securerandom"
|
|
15
|
+
|
|
16
|
+
config = McpConfigTranslator.for_provider(mcp_provider_key, mcp_servers)
|
|
17
|
+
config_json = JSON.generate(config)
|
|
18
|
+
|
|
19
|
+
if @executor.is_a?(DockerCommandExecutor)
|
|
20
|
+
# When running inside a Docker container, write the config file
|
|
21
|
+
# inside the container so the CLI process can read it.
|
|
22
|
+
# Track the path so cleanup_mcp_tempfiles! can remove it after execution.
|
|
23
|
+
container_path = "/tmp/agent_harness_mcp_#{SecureRandom.hex(8)}.json"
|
|
24
|
+
result = @executor.execute(
|
|
25
|
+
["sh", "-c", "cat > #{container_path}"],
|
|
26
|
+
stdin_data: config_json,
|
|
27
|
+
timeout: 5
|
|
28
|
+
)
|
|
29
|
+
unless result.success?
|
|
30
|
+
raise McpConfigurationError,
|
|
31
|
+
"Failed to write MCP config inside container: #{result.stderr}"
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
@mcp_docker_config_paths ||= []
|
|
35
|
+
@mcp_docker_config_paths << container_path
|
|
36
|
+
|
|
37
|
+
container_path
|
|
38
|
+
else
|
|
39
|
+
dir = working_dir || Dir.tmpdir
|
|
40
|
+
file = Tempfile.new(["agent_harness_mcp_", ".json"], dir)
|
|
41
|
+
file.write(config_json)
|
|
42
|
+
file.close
|
|
43
|
+
|
|
44
|
+
# Hold a reference so the Tempfile is not garbage-collected (and
|
|
45
|
+
# therefore deleted) before the CLI process reads it.
|
|
46
|
+
# Cleaned up by cleanup_mcp_tempfiles! after execution.
|
|
47
|
+
@mcp_config_tempfiles ||= []
|
|
48
|
+
@mcp_config_tempfiles << file
|
|
49
|
+
|
|
50
|
+
file.path
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def cleanup_mcp_tempfiles!
|
|
55
|
+
if @mcp_config_tempfiles
|
|
56
|
+
@mcp_config_tempfiles.each do |file|
|
|
57
|
+
file.close unless file.closed?
|
|
58
|
+
file.unlink
|
|
59
|
+
rescue
|
|
60
|
+
nil
|
|
61
|
+
end
|
|
62
|
+
@mcp_config_tempfiles = nil
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
if @mcp_docker_config_paths
|
|
66
|
+
@mcp_docker_config_paths.each do |path|
|
|
67
|
+
@executor.execute(["rm", "-f", path], timeout: 5)
|
|
68
|
+
rescue
|
|
69
|
+
nil
|
|
70
|
+
end
|
|
71
|
+
@mcp_docker_config_paths = nil
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
end
|
data/lib/agent_harness.rb
CHANGED
|
@@ -77,6 +77,47 @@ module AgentHarness
|
|
|
77
77
|
conductor.send_message(prompt, provider: provider, executor: executor, **options)
|
|
78
78
|
end
|
|
79
79
|
|
|
80
|
+
# Resolve a canonical extension definition by name or inline object.
|
|
81
|
+
#
|
|
82
|
+
# @param reference [Symbol, String, Extensions::Base]
|
|
83
|
+
# @return [Extensions::Base]
|
|
84
|
+
def extension(reference)
|
|
85
|
+
configuration.resolve_extension(reference)
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
# Load one or more extensions from disk through an adapter.
|
|
89
|
+
#
|
|
90
|
+
# @param path [String] extension file, directory, or package root
|
|
91
|
+
# @param adapter [Symbol, String, nil] optional explicit adapter
|
|
92
|
+
# @return [Array<Extensions::Base>]
|
|
93
|
+
def load_extensions(path, adapter: nil)
|
|
94
|
+
configuration.load_extensions(path, adapter: adapter)
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
# Discover and register all extensions found in a directory.
|
|
98
|
+
#
|
|
99
|
+
# @param directory [String] directory to scan
|
|
100
|
+
# @return [Array<Extensions::Base>]
|
|
101
|
+
def discover_extensions(directory)
|
|
102
|
+
configuration.discover_extensions(directory)
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
# Build a compatibility report for extensions against a provider.
|
|
106
|
+
#
|
|
107
|
+
# @param provider [Symbol, String, Providers::Base] target provider
|
|
108
|
+
# @param extensions [Array<Symbol, String, Extensions::Base>] extension references
|
|
109
|
+
# @return [Array<Extensions::CompatibilityReport>]
|
|
110
|
+
def extension_compatibility(provider:, extensions:)
|
|
111
|
+
provider_instance = provider.is_a?(Providers::Base) ? provider : self.provider(provider)
|
|
112
|
+
|
|
113
|
+
Array(extensions).map do |extension_ref|
|
|
114
|
+
Extensions::Compatibility.report(
|
|
115
|
+
provider: provider_instance,
|
|
116
|
+
extension: extension(extension_ref)
|
|
117
|
+
)
|
|
118
|
+
end
|
|
119
|
+
end
|
|
120
|
+
|
|
80
121
|
# Resolve a canonical sub-agent definition by name or inline payload.
|
|
81
122
|
#
|
|
82
123
|
# @param reference [Symbol, String, Hash, SubAgentConfig]
|
|
@@ -277,7 +318,10 @@ end
|
|
|
277
318
|
|
|
278
319
|
# Core components
|
|
279
320
|
require_relative "agent_harness/errors"
|
|
321
|
+
require_relative "agent_harness/extensions"
|
|
280
322
|
require_relative "agent_harness/mcp_server"
|
|
323
|
+
require_relative "agent_harness/mcp_config_loader"
|
|
324
|
+
require_relative "agent_harness/mcp_config_translator"
|
|
281
325
|
require_relative "agent_harness/sub_agent_config"
|
|
282
326
|
require_relative "agent_harness/sub_agent_file_loader"
|
|
283
327
|
require_relative "agent_harness/sub_agent_translator"
|
|
@@ -301,6 +345,7 @@ require_relative "agent_harness/providers/adapter"
|
|
|
301
345
|
require_relative "agent_harness/providers/base"
|
|
302
346
|
require_relative "agent_harness/providers/token_usage_parsing"
|
|
303
347
|
require_relative "agent_harness/providers/rate_limit_reset_parsing"
|
|
348
|
+
require_relative "agent_harness/providers/mcp_config_file_support"
|
|
304
349
|
require_relative "agent_harness/providers/anthropic"
|
|
305
350
|
require_relative "agent_harness/providers/aider"
|
|
306
351
|
require_relative "agent_harness/providers/codex"
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: agent-harness
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.11.
|
|
4
|
+
version: 0.11.3
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Bart Agapinan
|
|
@@ -107,6 +107,9 @@ files:
|
|
|
107
107
|
- lib/agent_harness/error_taxonomy.rb
|
|
108
108
|
- lib/agent_harness/errors.rb
|
|
109
109
|
- lib/agent_harness/execution_preparation.rb
|
|
110
|
+
- lib/agent_harness/extensions.rb
|
|
111
|
+
- lib/agent_harness/mcp_config_loader.rb
|
|
112
|
+
- lib/agent_harness/mcp_config_translator.rb
|
|
110
113
|
- lib/agent_harness/mcp_server.rb
|
|
111
114
|
- lib/agent_harness/openai_compatible_transport.rb
|
|
112
115
|
- lib/agent_harness/orchestration/circuit_breaker.rb
|
|
@@ -126,6 +129,7 @@ files:
|
|
|
126
129
|
- lib/agent_harness/providers/gemini.rb
|
|
127
130
|
- lib/agent_harness/providers/github_copilot.rb
|
|
128
131
|
- lib/agent_harness/providers/kilocode.rb
|
|
132
|
+
- lib/agent_harness/providers/mcp_config_file_support.rb
|
|
129
133
|
- lib/agent_harness/providers/mistral_vibe.rb
|
|
130
134
|
- lib/agent_harness/providers/opencode.rb
|
|
131
135
|
- lib/agent_harness/providers/rate_limit_reset_parsing.rb
|