smith-agents 0.4.3 → 0.4.4
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/CHANGELOG.md +26 -0
- data/README.md +1 -1
- data/lib/smith/agent/lifecycle.rb +30 -10
- data/lib/smith/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 23c6a49b741d4ff6cfab0707ca1d917b484dc708106d1c892b4f90e2002e5b80
|
|
4
|
+
data.tar.gz: 72cfe59171b0f759f0312ff062f58c23aeb9a9f7e738f1603dfaf4a9174f9fbb
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 245ac5f48372808860db62cc661bf9c9e5bf2a1a3bc4082533b16159b09c50b113bead696d4147e10e850fe0b7fff8cef775da17aa749fc4b7a5574058b765f7
|
|
7
|
+
data.tar.gz: 7837da6f0c9855f03a0936bdec22279ec6da9c8864fae27de8ab495a334b98654617147b36b7759d171dc19ad13ae80448b18fa3c7da4f16bf84f7c378c004bf
|
data/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,32 @@ Format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/). Version
|
|
|
6
6
|
|
|
7
7
|
## [Unreleased]
|
|
8
8
|
|
|
9
|
+
## [0.4.4] - 2026-07-10
|
|
10
|
+
|
|
11
|
+
Patch release for provider-safe workflow handoffs. Smith keeps accepted agent
|
|
12
|
+
outputs in durable session history while adapting only the next provider call
|
|
13
|
+
when a completed workflow stage would otherwise look like an unsupported
|
|
14
|
+
assistant prefill.
|
|
15
|
+
|
|
16
|
+
### Fixed
|
|
17
|
+
|
|
18
|
+
- Adapt workflow-prepared provider input that ends with an accepted assistant
|
|
19
|
+
result by adding a non-persisted user continuation for the next agent call.
|
|
20
|
+
This preserves Smith session history while avoiding unsupported assistant
|
|
21
|
+
prefilling on provider models that require a user turn before completion.
|
|
22
|
+
Provider preparation now also reads string-keyed roles and content restored
|
|
23
|
+
through JSON host persistence. Explicit assistant-prefill seed messages remain
|
|
24
|
+
unchanged unless they match Smith's recorded accepted workflow output.
|
|
25
|
+
|
|
26
|
+
### Verification
|
|
27
|
+
|
|
28
|
+
- Default suite: 932 examples, 0 failures.
|
|
29
|
+
- Practical gem-level JSON persistence/restore probe with a 25-branch parallel
|
|
30
|
+
handoff, provider-safe message ordering, non-persisted continuation, and
|
|
31
|
+
explicit assistant-prefill preservation.
|
|
32
|
+
- Smith Runtime host verification on Ruby 4.0.1 and Rails 8.1.3: 139 tests,
|
|
33
|
+
391 assertions, 0 failures, plus a process-level restored workflow run.
|
|
34
|
+
|
|
9
35
|
## [0.4.3] - 2026-07-05
|
|
10
36
|
|
|
11
37
|
### Documentation
|
data/README.md
CHANGED
|
@@ -3,6 +3,10 @@
|
|
|
3
3
|
module Smith
|
|
4
4
|
class Agent
|
|
5
5
|
module Lifecycle
|
|
6
|
+
WORKFLOW_CONTINUATION_MESSAGE =
|
|
7
|
+
"Use the preceding assistant result as input and perform your assigned workflow step."
|
|
8
|
+
private_constant :WORKFLOW_CONTINUATION_MESSAGE
|
|
9
|
+
|
|
6
10
|
TRANSIENT_ERRORS = [
|
|
7
11
|
RubyLLM::ServerError, RubyLLM::ServiceUnavailableError,
|
|
8
12
|
RubyLLM::OverloadedError, RubyLLM::RateLimitError
|
|
@@ -111,6 +115,7 @@ module Smith
|
|
|
111
115
|
def add_prepared_input(chat, prepared_input)
|
|
112
116
|
return unless prepared_input
|
|
113
117
|
|
|
118
|
+
prepared_input = provider_safe_prepared_input(prepared_input)
|
|
114
119
|
system_messages, other_messages = prepared_input.partition do |message|
|
|
115
120
|
message_role(message) == :system
|
|
116
121
|
end
|
|
@@ -119,6 +124,22 @@ module Smith
|
|
|
119
124
|
other_messages.each { |message| chat.add_message(message) }
|
|
120
125
|
end
|
|
121
126
|
|
|
127
|
+
def provider_safe_prepared_input(prepared_input)
|
|
128
|
+
messages = prepared_input.to_a
|
|
129
|
+
return messages unless workflow_handoff?(messages)
|
|
130
|
+
|
|
131
|
+
messages + [{ role: :user, content: WORKFLOW_CONTINUATION_MESSAGE }]
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
def workflow_handoff?(messages)
|
|
135
|
+
message = messages.reverse_each.find { |candidate| message_role(candidate) != :system }
|
|
136
|
+
return false unless message
|
|
137
|
+
return false unless message_role(message) == :assistant
|
|
138
|
+
return false unless defined?(@last_output) && !@last_output.nil?
|
|
139
|
+
|
|
140
|
+
message_content(message) == @last_output
|
|
141
|
+
end
|
|
142
|
+
|
|
122
143
|
def merge_system_messages!(chat, prepared_system_messages)
|
|
123
144
|
return prepared_system_messages.each { |message| chat.add_message(message) } unless chat.respond_to?(:messages)
|
|
124
145
|
|
|
@@ -143,19 +164,18 @@ module Smith
|
|
|
143
164
|
end
|
|
144
165
|
|
|
145
166
|
def message_role(message)
|
|
146
|
-
|
|
147
|
-
message.role&.to_sym
|
|
148
|
-
else
|
|
149
|
-
message[:role]&.to_sym
|
|
150
|
-
end
|
|
167
|
+
message_attribute(message, :role)&.to_sym
|
|
151
168
|
end
|
|
152
169
|
|
|
153
170
|
def message_content(message)
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
171
|
+
message_attribute(message, :content)
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
def message_attribute(message, name)
|
|
175
|
+
return message.public_send(name) if message.respond_to?(name)
|
|
176
|
+
return message[name] if message.respond_to?(:key?) && message.key?(name)
|
|
177
|
+
|
|
178
|
+
message[name.to_s]
|
|
159
179
|
end
|
|
160
180
|
|
|
161
181
|
def fallback_eligible?(error)
|
data/lib/smith/version.rb
CHANGED