agent-harness 0.44.0 → 0.44.2
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 +15 -0
- data/README.md +3 -2
- data/docs/provider-neutral-api-execution-contract.md +95 -36
- data/lib/agent_harness/api/chat_transport.rb +3 -1
- data/lib/agent_harness/api/ruby_llm_chat_adapter.rb +6 -30
- data/lib/agent_harness/providers/anthropic.rb +1 -1
- data/lib/agent_harness/providers/omp.rb +1 -1
- data/lib/agent_harness/version.rb +1 -1
- metadata +5 -5
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: efd5625d515cf2a89d7390f05addbb757604262e14276b01a098dd1e2a601455
|
|
4
|
+
data.tar.gz: 1e51f13a384e660a59dccc235800ef4d1a3c3f4e9044753da6117773a34944d6
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: bdd3e8799f3075fb7e84ddac4a4d80b45ea1baab74e37dc1f393cc231a60ec31e59cdd3516ab4cef0139f23a8cbf20ba08ad7fa2c03b56446b66264a108ac660
|
|
7
|
+
data.tar.gz: c858106c4c8a83b09941cdbb16b447d4fc814e693be3c0b88f5123215187a3440322a4dc430b93d26be4286570cdb8854a9431c038bebab7b22e605c01fdbc38
|
data/CHANGELOG.md
CHANGED
|
@@ -2,10 +2,25 @@
|
|
|
2
2
|
|
|
3
3
|
### Features
|
|
4
4
|
|
|
5
|
+
* verify RDR-072's published capability artifacts and migration limits, retain the application chat loop over normalized transport, and remove the private RubyLLM streaming-refusal patch in favor of an explicit non-streaming schema boundary ([#437](https://github.com/viamin/agent-harness/issues/437)).
|
|
5
6
|
* expose normalized API chat transport and schema-constrained responses with preserved JSON text, locally validated parsed values, and explicit refusal, truncation, invalid JSON, schema mismatch, and unsupported-mode outcomes; this combined delivery supersedes the separate chat-transport work item ([#433](https://github.com/viamin/agent-harness/issues/433), [#434](https://github.com/viamin/agent-harness/issues/434)).
|
|
6
7
|
* add runner model compatibility contract (`AgentHarness.model_compatibility`) with structured `ModelCompatibility::Result` outcomes. Codex exposes static facts for CLI-gated models (e.g. `gpt-5.5` requires Codex CLI `>= 0.116.0`), a baseline supported-model list, supported auth modes, and a `DEFAULT_COMPATIBLE_MODEL_ID` fallback so downstream orchestrators can validate tier/model assignments before scheduling agent runs ([#259](https://github.com/viamin/agent-harness/issues/259)).
|
|
7
8
|
* **auth:** add provider-owned PKCE code-exchange API for Claude OAuth (`AgentHarness::Authentication.exchange_code`). Takes an authorization code plus PKCE verifier (and `redirect_uri`/`client_id`), posts an `authorization_code` grant to the Claude token endpoint, and persists the resulting access/refresh tokens in the native `claudeAiOauth` shape. Adds `exchange_code_supported?` and a `code_exchange` key to `auth_capabilities` ([#266](https://github.com/viamin/agent-harness/issues/266)).
|
|
8
9
|
|
|
10
|
+
## [0.44.2](https://github.com/viamin/agent-harness/compare/agent-harness/v0.44.1...agent-harness/v0.44.2) (2026-09-27)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
### Bug Fixes
|
|
14
|
+
|
|
15
|
+
* **deps-dev:** bump @oh-my-pi/pi-coding-agent from 18.2.4 to 18.3.0 in /vendor/pins/omp ([#454](https://github.com/viamin/agent-harness/issues/454)) ([77b1cc6](https://github.com/viamin/agent-harness/commit/77b1cc68b4bfe27f5a70c92ff690ea7ea836ee7c))
|
|
16
|
+
|
|
17
|
+
## [0.44.1](https://github.com/viamin/agent-harness/compare/agent-harness/v0.44.0...agent-harness/v0.44.1) (2026-09-27)
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
### Bug Fixes
|
|
21
|
+
|
|
22
|
+
* **deps-dev:** bump @anthropic-ai/claude-code from 2.1.275 to 2.1.282 in /vendor/pins/claude ([#453](https://github.com/viamin/agent-harness/issues/453)) ([1848bbb](https://github.com/viamin/agent-harness/commit/1848bbb03653e0b64524fbffbcc939eb8542ad2f))
|
|
23
|
+
|
|
9
24
|
## [0.44.0](https://github.com/viamin/agent-harness/compare/agent-harness/v0.43.0...agent-harness/v0.44.0) (2026-09-25)
|
|
10
25
|
|
|
11
26
|
|
data/README.md
CHANGED
|
@@ -806,8 +806,9 @@ Health checks run five steps per provider: registration, CLI availability, authe
|
|
|
806
806
|
The proposed provider-neutral API execution boundary for embeddings, chat,
|
|
807
807
|
structured output, usage, and optional persistence is documented in the
|
|
808
808
|
[Provider-Neutral API Execution Contract](docs/provider-neutral-api-execution-contract.md).
|
|
809
|
-
|
|
810
|
-
evidence
|
|
809
|
+
That document records the shipped capability versions, migration examples,
|
|
810
|
+
verified limits, and the evidence-backed decision to retain the application
|
|
811
|
+
conversation loop over the normalized transport.
|
|
811
812
|
|
|
812
813
|
```bash
|
|
813
814
|
# Install dependencies
|
|
@@ -712,40 +712,100 @@ types stay behind the harness boundary.
|
|
|
712
712
|
|
|
713
713
|
## Compatibility and release evidence
|
|
714
714
|
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
715
|
+
The following RubyGems releases are the first installable artifacts for each
|
|
716
|
+
capability. Pin the capability's minimum version during migration; do not infer
|
|
717
|
+
support from an issue, branch, or Git tag.
|
|
718
|
+
|
|
719
|
+
| Capability | First installable version | Contract / delivery | Install check |
|
|
720
|
+
| --- | ---: | ---: | --- |
|
|
721
|
+
| Native embeddings | `0.40.0` | [#432](https://github.com/viamin/agent-harness/issues/432) / [#439](https://github.com/viamin/agent-harness/issues/439) | `gem install agent-harness -v 0.40.0` |
|
|
722
|
+
| Normalized chat, tools, and streaming | `0.41.0` | [#434](https://github.com/viamin/agent-harness/issues/434) / [#441](https://github.com/viamin/agent-harness/issues/441) | `gem install agent-harness -v 0.41.0` |
|
|
723
|
+
| Attempt usage and cost | `0.42.0` | [#435](https://github.com/viamin/agent-harness/issues/435) / [#443](https://github.com/viamin/agent-harness/issues/443) | `gem install agent-harness -v 0.42.0` |
|
|
724
|
+
| Schema-constrained responses | `0.43.0` | [#436](https://github.com/viamin/agent-harness/issues/436) / [#442](https://github.com/viamin/agent-harness/issues/442) | `gem install agent-harness -v 0.43.0` |
|
|
725
|
+
|
|
726
|
+
All four are plain-Ruby capabilities. They load without Rails or Active Record,
|
|
727
|
+
create no tables, and require no migration. The runtime floor is Ruby 3.2 and
|
|
728
|
+
RubyLLM 2.x. The four released versions above still pin `ruby_llm = 2.0.0` and
|
|
729
|
+
prepend the private `AgentHarness::Api::RubyLlmResponsesStreamingRefusal`
|
|
730
|
+
module into `RubyLLM::Protocols::Responses` process-wide. The prepend-free,
|
|
731
|
+
public-API-only boundary (RubyLLM's public context, chat, message, tool, token
|
|
732
|
+
and cost APIs only; no private method calls, no downstream monkey patch, and a
|
|
733
|
+
loosened `ruby_llm ~> 2.0` dependency) lands in the first release published
|
|
734
|
+
after [#437](https://github.com/viamin/agent-harness/issues/437); record that
|
|
735
|
+
version here once it exists, because support must not be inferred from an
|
|
736
|
+
issue, branch, or Git tag.
|
|
737
|
+
|
|
738
|
+
### Migration examples and limits
|
|
739
|
+
|
|
740
|
+
- **Embeddings (`>= 0.40.0`):** replace a downstream direct/proxy HTTP patch
|
|
741
|
+
with `AgentHarness.embed`, passing credentials, endpoint and headers on each
|
|
742
|
+
request. Remove the old retry layer after direct and proxy contract tests
|
|
743
|
+
pass. The operation is OpenAI-compatible, API-key only, has batch-total usage
|
|
744
|
+
only, and does not estimate missing tokens.
|
|
745
|
+
- **Chat (`>= 0.41.0`):** construct `AgentHarness::Api::ChatTransport` and send
|
|
746
|
+
one normalized request for each model step. Keep the application loop and
|
|
747
|
+
append completed tool results to the next request. Verified protocols are
|
|
748
|
+
Anthropic Messages and OpenAI Responses/Chat Completions; custom compatible
|
|
749
|
+
endpoints must explicitly choose Chat Completions. Media, custom auth modes,
|
|
750
|
+
protocol probing, and request-local connect timeouts are unsupported.
|
|
751
|
+
- **Attempt accounting (`>= 0.42.0`):** persist each entry in `result[:attempts]`
|
|
752
|
+
once by `attempt_id`, including failed and cancelled attempts. Do not add
|
|
753
|
+
aggregate `result[:usage]` again, convert unknown usage to zero, or wrap the
|
|
754
|
+
call in another provider-request retry loop. Paid still owns durable budget
|
|
755
|
+
accounting, workflow recovery and runner changes.
|
|
756
|
+
- **Schema (`>= 0.43.0`):** set `operation: :schema`, `schema_mode:
|
|
757
|
+
:json_schema`, and provide a named JSON Schema. The harness preserves the
|
|
758
|
+
provider text and validates it locally; use a non-streaming schema request.
|
|
759
|
+
JSON-only mode, schema repair, and model-specific capability discovery are
|
|
760
|
+
also unsupported. Rejection of streamed schema requests
|
|
761
|
+
(`unsupported/structured_output_not_supported`) and removal of the private
|
|
762
|
+
RubyLLM streaming-refusal shim land in the first release published after
|
|
763
|
+
this change; the released `0.43.0` still contains that shim and executes
|
|
764
|
+
streamed schema requests.
|
|
765
|
+
|
|
766
|
+
For every migration, run the consumer contract suite with tenant-specific
|
|
767
|
+
credentials and headers, custom endpoints, auth and transient failures,
|
|
768
|
+
cancellation, and the configured attempt bound. Inspect captured logs for
|
|
769
|
+
credentials and request bodies. Record the exact Paid host and agent-image
|
|
770
|
+
artifact versions before enabling that scope.
|
|
771
|
+
|
|
772
|
+
### Verification and retained paths
|
|
773
|
+
|
|
774
|
+
The [#431 contract audit](https://github.com/viamin/agent-harness/issues/431)
|
|
775
|
+
is implemented by the upstream specs under `spec/agent_harness/embeddings_spec.rb`
|
|
776
|
+
and `spec/agent_harness/api/`. Those specs cover request-local credential, endpoint and header
|
|
777
|
+
isolation; reserved authentication headers; classified errors; bounded retries
|
|
778
|
+
with RubyLLM retries disabled; cancellation; partial streams; stable attempt
|
|
779
|
+
identity; usage/cost serialization; secret-free observer data; schema refusal,
|
|
780
|
+
truncation and validation; and the public-only RubyLLM integration. The normal
|
|
781
|
+
provider, command-executor, model-discovery and authentication suites remain the
|
|
782
|
+
CLI/subscription regression coverage.
|
|
783
|
+
|
|
784
|
+
CLI and subscription execution, legacy `TextTransport` and
|
|
785
|
+
`OpenAICompatibleTransport`, provider selection, workflow recovery, and Paid's
|
|
786
|
+
durable accounting are intentionally unchanged. No credential or authentication
|
|
787
|
+
mode is selected implicitly. Rails persistence and conversation state round
|
|
788
|
+
trips were not adopted.
|
|
789
|
+
|
|
790
|
+
### Retained-loop closeout
|
|
791
|
+
|
|
792
|
+
The completed boundary is normalized transport with Paid's loop retained.
|
|
793
|
+
`Api::ChatTransport` performs one assistant response and never executes tools;
|
|
794
|
+
Paid continues to own authorization, confirmation policy, tool side effects,
|
|
795
|
+
transcript persistence, approval resumption and crash recovery. Delegating the
|
|
796
|
+
loop would require new persistence, tenant/audit adapters and recovery glue in
|
|
797
|
+
both repositories without removing those application responsibilities. There
|
|
798
|
+
is therefore no demonstrated net maintenance reduction or safe migration of
|
|
799
|
+
pending conversations. Under RDR-072 this evidence-backed retained-loop result
|
|
800
|
+
is complete, not deferred delegation.
|
|
801
|
+
|
|
802
|
+
Downstream adoption is tracked in
|
|
803
|
+
[viamin/paid#4014](https://github.com/viamin/paid/issues/4014); preservation of
|
|
804
|
+
Codex subscription discovery/recovery during dependency adoption is tracked in
|
|
805
|
+
[viamin/paid#3995](https://github.com/viamin/paid/issues/3995). Close parent
|
|
806
|
+
[agent-harness#430](https://github.com/viamin/agent-harness/issues/430) only
|
|
807
|
+
after those consumers record their exact host/image artifacts and passing
|
|
808
|
+
integration evidence for every scope they enable.
|
|
749
809
|
|
|
750
810
|
### Loop-delegation evaluation evidence (retained loop)
|
|
751
811
|
|
|
@@ -789,5 +849,4 @@ For every capability, release evidence must name:
|
|
|
789
849
|
Paid issue `viamin/paid#4014` should receive this compatibility result, the
|
|
790
850
|
state-restoration conclusion, the stable-ID gap, the per-capability release
|
|
791
851
|
evidence, and the retained-loop outcome of the delegation evaluation.
|
|
792
|
-
Downstream adoption cannot proceed from this
|
|
793
|
-
from a Git tag alone.
|
|
852
|
+
Downstream adoption cannot proceed from this closeout or from a Git tag alone.
|
|
@@ -373,7 +373,9 @@ module AgentHarness
|
|
|
373
373
|
end
|
|
374
374
|
|
|
375
375
|
def schema_mode_supported?
|
|
376
|
-
|
|
376
|
+
return true unless schema_operation?
|
|
377
|
+
|
|
378
|
+
request[:stream] != true && (!request[:schema_mode] || request[:schema_mode].to_sym == :json_schema)
|
|
377
379
|
end
|
|
378
380
|
|
|
379
381
|
def schema_payload
|
|
@@ -5,22 +5,6 @@ require "ruby_llm"
|
|
|
5
5
|
|
|
6
6
|
module AgentHarness
|
|
7
7
|
module Api
|
|
8
|
-
# RubyLLM 2.0.0 flattens Responses API refusal deltas into ordinary text
|
|
9
|
-
# chunks and offers no public access to their event type. The gemspec pins
|
|
10
|
-
# that exact release so this compatibility shim cannot silently outlive the
|
|
11
|
-
# private parser shape it targets. Remove it when RubyLLM exposes refusals.
|
|
12
|
-
module RubyLlmResponsesStreamingRefusal
|
|
13
|
-
module RefusalChunk; end
|
|
14
|
-
|
|
15
|
-
def build_chunk(data)
|
|
16
|
-
super.tap do |chunk|
|
|
17
|
-
chunk.extend(RefusalChunk) if data["type"] == "response.refusal.delta"
|
|
18
|
-
end
|
|
19
|
-
end
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
RubyLLM::Protocols::Responses.prepend(RubyLlmResponsesStreamingRefusal)
|
|
23
|
-
|
|
24
8
|
# Translates the normalized public chat values to RubyLLM public objects.
|
|
25
9
|
class RubyLlmChatAdapter
|
|
26
10
|
class UnsupportedOptionError < StandardError; end
|
|
@@ -38,12 +22,12 @@ module AgentHarness
|
|
|
38
22
|
provider_usage_reported = false
|
|
39
23
|
chat = prepared_chat || prepare(candidate:, messages:, tools:, max_output_tokens:, temperature:, timeout:,
|
|
40
24
|
schema:, on_accounting:, provider_usage: -> { provider_usage_reported })
|
|
41
|
-
response
|
|
25
|
+
response = generate(chat, stream, cancellation) do |event|
|
|
42
26
|
provider_usage_reported = true if event[:type] == :usage_updated
|
|
43
27
|
on_event&.call(event)
|
|
44
28
|
end
|
|
45
29
|
emit_completed_tool_calls(response, &on_event) if stream
|
|
46
|
-
normalize_response(response
|
|
30
|
+
normalize_response(response)
|
|
47
31
|
end
|
|
48
32
|
|
|
49
33
|
def prepare(candidate:, messages:, tools:, max_output_tokens:, temperature:, timeout:, on_accounting: nil,
|
|
@@ -61,7 +45,6 @@ module AgentHarness
|
|
|
61
45
|
# duplicate cumulative reports are not re-emitted.
|
|
62
46
|
class StreamState
|
|
63
47
|
attr_accessor :input_tokens, :output_tokens
|
|
64
|
-
attr_reader :refusal
|
|
65
48
|
|
|
66
49
|
def initialize
|
|
67
50
|
@provider_id_by_key = {}
|
|
@@ -69,7 +52,6 @@ module AgentHarness
|
|
|
69
52
|
@latest_provider_id = nil
|
|
70
53
|
@input_tokens = nil
|
|
71
54
|
@output_tokens = nil
|
|
72
|
-
@refusal = false
|
|
73
55
|
end
|
|
74
56
|
|
|
75
57
|
# Links a stream chunk key to its provider call id, returning true
|
|
@@ -90,10 +72,6 @@ module AgentHarness
|
|
|
90
72
|
total = (input_tokens + output_tokens) if input_tokens && output_tokens
|
|
91
73
|
{input_tokens: input_tokens, output_tokens: output_tokens, total_tokens: total}
|
|
92
74
|
end
|
|
93
|
-
|
|
94
|
-
def observe(chunk)
|
|
95
|
-
@refusal ||= chunk.is_a?(RubyLlmResponsesStreamingRefusal::RefusalChunk)
|
|
96
|
-
end
|
|
97
75
|
end
|
|
98
76
|
|
|
99
77
|
private
|
|
@@ -182,10 +160,10 @@ module AgentHarness
|
|
|
182
160
|
end
|
|
183
161
|
|
|
184
162
|
def generate(chat, stream, cancellation)
|
|
185
|
-
return
|
|
163
|
+
return generate_without_events(chat, cancellation) unless stream
|
|
186
164
|
|
|
187
165
|
state = StreamState.new
|
|
188
|
-
|
|
166
|
+
chat.generate do |chunk|
|
|
189
167
|
if cancelled?(cancellation)
|
|
190
168
|
chat.cancel
|
|
191
169
|
raise RubyLLM::CancelledError
|
|
@@ -193,7 +171,6 @@ module AgentHarness
|
|
|
193
171
|
|
|
194
172
|
stream_events(chunk, state).each { |event| yield event }
|
|
195
173
|
end
|
|
196
|
-
[response, state.refusal]
|
|
197
174
|
end
|
|
198
175
|
|
|
199
176
|
def generate_without_events(chat, cancellation)
|
|
@@ -259,7 +236,6 @@ module AgentHarness
|
|
|
259
236
|
end
|
|
260
237
|
|
|
261
238
|
def stream_events(chunk, state)
|
|
262
|
-
state.observe(chunk)
|
|
263
239
|
[text_event(chunk), *tool_call_events(chunk, state), usage_event(chunk, state)].compact
|
|
264
240
|
end
|
|
265
241
|
|
|
@@ -325,14 +301,14 @@ module AgentHarness
|
|
|
325
301
|
end
|
|
326
302
|
end
|
|
327
303
|
|
|
328
|
-
def normalize_response(response
|
|
304
|
+
def normalize_response(response)
|
|
329
305
|
{
|
|
330
306
|
content: response.content || "",
|
|
331
307
|
model: response.model,
|
|
332
308
|
finish_reason: response.finish_reason,
|
|
333
309
|
usage: normalize_usage(response.tokens),
|
|
334
310
|
tool_calls: Array(response.tool_calls&.values).map { |call| normalize_tool_call(call) },
|
|
335
|
-
refusal:
|
|
311
|
+
refusal: refusal?(response)
|
|
336
312
|
}
|
|
337
313
|
end
|
|
338
314
|
|
|
@@ -27,7 +27,7 @@ module AgentHarness
|
|
|
27
27
|
|
|
28
28
|
# Model name pattern for Anthropic Claude models
|
|
29
29
|
MODEL_PATTERN = /^claude-[\d.-]+-(?:opus|sonnet|haiku)(?:-\d{8})?$/i
|
|
30
|
-
SUPPORTED_CLI_VERSION = "2.1.
|
|
30
|
+
SUPPORTED_CLI_VERSION = "2.1.282"
|
|
31
31
|
SUPPORTED_CLI_REQUIREMENT = Gem::Requirement.new(">= #{SUPPORTED_CLI_VERSION}", "< 2.2.0").freeze
|
|
32
32
|
|
|
33
33
|
# Matches semver (e.g. "2.1.92"), optional pre-release (e.g. "2.1.92-beta.1"),
|
|
@@ -12,7 +12,7 @@ module AgentHarness
|
|
|
12
12
|
# CLI.
|
|
13
13
|
class OhMyPi < Base
|
|
14
14
|
CLI_PACKAGE = "@oh-my-pi/pi-coding-agent"
|
|
15
|
-
SUPPORTED_CLI_VERSION = "18.
|
|
15
|
+
SUPPORTED_CLI_VERSION = "18.3.0"
|
|
16
16
|
SUPPORTED_CLI_REQUIREMENT = Gem::Requirement.new("= #{SUPPORTED_CLI_VERSION}").freeze
|
|
17
17
|
|
|
18
18
|
# Bun runtime requirements. The omp entrypoint is
|
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.44.
|
|
4
|
+
version: 0.44.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Bart Agapinan
|
|
@@ -47,16 +47,16 @@ dependencies:
|
|
|
47
47
|
name: ruby_llm
|
|
48
48
|
requirement: !ruby/object:Gem::Requirement
|
|
49
49
|
requirements:
|
|
50
|
-
- -
|
|
50
|
+
- - "~>"
|
|
51
51
|
- !ruby/object:Gem::Version
|
|
52
|
-
version: 2.0
|
|
52
|
+
version: '2.0'
|
|
53
53
|
type: :runtime
|
|
54
54
|
prerelease: false
|
|
55
55
|
version_requirements: !ruby/object:Gem::Requirement
|
|
56
56
|
requirements:
|
|
57
|
-
- -
|
|
57
|
+
- - "~>"
|
|
58
58
|
- !ruby/object:Gem::Version
|
|
59
|
-
version: 2.0
|
|
59
|
+
version: '2.0'
|
|
60
60
|
- !ruby/object:Gem::Dependency
|
|
61
61
|
name: rake
|
|
62
62
|
requirement: !ruby/object:Gem::Requirement
|