Skip to content

Commit ef338ef

Browse files
arcaputo3claude
andcommitted
fix: address PR review feedback
- Wrap bridge_metadata parsing with guardTopLevelUnknown for consistency - Add @jsonField("slash_commands") annotation for JSON round-trip correctness - Restore caret in package.json version specifier - Add edge-case tests: StopFailure with missing error, empty slash_commands Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent f5f1943 commit ef338ef

File tree

6 files changed

+36
-8
lines changed

6 files changed

+36
-8
lines changed

bun.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
},
1111
"dependencies": {
1212
"@a2a-js/sdk": "^0.3.12",
13-
"@anthropic-ai/claude-agent-sdk": "0.2.78",
13+
"@anthropic-ai/claude-agent-sdk": "^0.2.78",
1414
"zod": "^4.0.0"
1515
},
1616
"devDependencies": {

src/com/tjclp/scalagent/messages/AgentMessage.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ enum AgentMessage:
168168

169169
/** Bridge metadata message carrying slash commands */
170170
case BridgeMetadata(
171-
slashCommands: List[String],
171+
@jsonField("slash_commands") slashCommands: List[String],
172172
uuid: MessageUuid,
173173
sessionId: SessionId
174174
)

src/com/tjclp/scalagent/streaming/MessageConverter.scala

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -204,11 +204,13 @@ object MessageConverter:
204204
parseApiRetryMessage(obj, raw)
205205
}
206206
case Some("bridge_metadata") =>
207-
AgentMessage.BridgeMetadata(
208-
slashCommands = stringArrayField(obj, "slash_commands"),
209-
uuid = requiredUuid(obj, raw),
210-
sessionId = requiredSessionId(obj, raw)
211-
)
207+
guardTopLevelUnknown(raw, "system", Some("bridge_metadata"), context) {
208+
AgentMessage.BridgeMetadata(
209+
slashCommands = stringArrayField(obj, "slash_commands"),
210+
uuid = requiredUuid(obj, raw),
211+
sessionId = requiredSessionId(obj, raw)
212+
)
213+
}
212214
case other =>
213215
AgentMessage.System(
214216
event = parseSystemEvent(obj, raw, other, context),

test/src/com/tjclp/scalagent/hooks/HookCallbackSpec.scala

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,17 @@ class HookCallbackSpec extends FunSuite:
182182
case other => fail(s"Expected StopFailure, got: $other")
183183
}
184184

185+
test("parseHookInput handles StopFailure with missing error defaults to Unknown"):
186+
val raw = baseInput("StopFailure")
187+
188+
parseInput(raw).map {
189+
case input: HookInput.StopFailure =>
190+
assertEquals(input.error, AssistantMessageError.Unknown)
191+
assertEquals(input.errorDetails, None)
192+
assertEquals(input.lastAssistantMessage, None)
193+
case other => fail(s"Expected StopFailure, got: $other")
194+
}
195+
185196
test("parseHookInput handles InstructionsLoaded with agent metadata"):
186197
val raw = baseInput("InstructionsLoaded")
187198
raw.file_path = "/tmp/project/CLAUDE.md"

test/src/com/tjclp/scalagent/streaming/MessageConverterSpec.scala

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -403,6 +403,21 @@ class MessageConverterSpec extends FunSuite:
403403
case other =>
404404
fail(s"Expected BridgeMetadata, got: $other")
405405

406+
test("parses bridge_metadata with empty slash_commands"):
407+
val raw = js.Dynamic.literal(
408+
`type` = "system",
409+
subtype = "bridge_metadata",
410+
slash_commands = js.Array[String](),
411+
uuid = "msg-bridge-2",
412+
session_id = "session-1"
413+
)
414+
415+
MessageConverter.fromRaw(raw) match
416+
case AgentMessage.BridgeMetadata(slashCommands, _, _) =>
417+
assertEquals(slashCommands, Nil)
418+
case other =>
419+
fail(s"Expected BridgeMetadata, got: $other")
420+
406421
test("parses task_progress with summary"):
407422
val raw = js.Dynamic.literal(
408423
`type` = "system",

0 commit comments

Comments
 (0)