chore: bump SDK to 0.2.77 with parity updates#24
Conversation
The A2A SDK's event queue breaks on whichever event arrives first. Publishing the final status-update before the message event ensures the task store transitions to "completed" before the message is emitted. Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
New SDK types and APIs added in 0.2.76–0.2.77: - PostCompact hook event: fires after context compaction with compact_summary - HookInput.PostCompact case class and parseHookInput handler - AgentMessage.ApiRetry: new system/api_retry message for retryable errors - Claude.forkSession(): fork a session to a new branch with fresh UUIDs - QueryStream.applyFlagSettings(): apply Settings mid-session - AccountInfo.apiProvider: 'firstParty' | 'bedrock' | 'vertex' | 'foundry' - HookInput.PermissionRequest: new title/displayName/description fields - InstructionsLoadReason.Compact: new 'compact' load_reason value - SandboxFilesystemConfig: new allowRead and allowManagedReadPathsOnly fields Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
PR Review: chore: bump SDK to 0.2.77 with parity updatesGood SDK parity update overall. The A2A ordering fix is correct and well-documented. A few observations below: Bugs / Potential Issues
val opts = js.Dynamic.literal()
// ...
val jsOpts: js.UndefOr[js.Dynamic] = opts // always defined, never js.undefinedAssigning a val opts = dir match
case Some(d) => js.Dynamic.literal(dir = d)
case None => js.undefinedThis is unlikely to break anything in practice (the SDK should tolerate an empty options object), but it's inconsistent with the codebase convention and worth fixing for correctness. Design Concerns
attempt = intField(obj, "attempt").getOrElse(0),
maxRetries = intField(obj, "max_retries").getOrElse(0),
retryDelayMs = longField(obj, "retry_delay_ms").getOrElse(0L),A default of
This bypasses Scala's type system entirely. If the codebase has a
The SDK documents this as Minor Observations
This parameter is a message UUID. Using Version constraint loosening ( The constraint changed from the exact pin What Looks Good
🤖 Generated with Claude Code |
- Pass js.undefined instead of empty {} when all options are None,
matching the pattern used by getSessionInfo/renameSession
- Change upToMessageId from Option[String] to Option[MessageUuid]
for type-safe message UUID references
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Code Review — chore: bump SDK to 0.2.77 with parity updatesOverall this is a clean, focused parity update that mirrors the upstream SDK additions faithfully. The A2A ordering fix is particularly well-documented. A few items worth discussing: Issues / Concerns1. Version pin changed to range (
|
- forkSession result uses js.UndefOr with meaningful error on missing sessionId - Add MessageConverter tests: api_retry parsing, null error_status handling - Add HookCallback tests: PostCompact parsing, PermissionRequest title/displayName/description - Add HookInputEnum test: InstructionsLoadReason.Compact round-trip Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
PR Review: chore: bump SDK to 0.2.77 with parity updatesOverall this is a clean, well-structured parity update. The changes are consistent with existing patterns in the codebase. A few things worth flagging: Potential Issues1. Version range change in -"@anthropic-ai/claude-agent-sdk": "0.2.75",
+"@anthropic-ai/claude-agent-sdk": "^0.2.77",The original version was pinned exactly ( 2. ZIO
.fromPromiseJS(SdkModule.forkSession(sessionId.value, jsOpts)) // E = Throwable
.flatMap { result =>
val sid = result.sessionId.asInstanceOf[js.UndefOr[String]].toOption
ZIO.fromOption(sid).mapError(_ =>
new RuntimeException("forkSession: missing sessionId in response") // E = RuntimeException
)
}
.map(SessionId(_))
.mapError(AgentError.fromThrowable) // This only catches the outer Throwable; inner RuntimeException is already a Throwable so it works, but the intent is obscuredThis compiles and works (since ZIO.fromOption(sid).orElseFail(AgentError.fromThrowable(
RuntimeException("forkSession: missing sessionId in response")
))3. def applyFlagSettings(settings: js.Dynamic): Task[Unit] =
ZIO.fromPromiseJS(rawQuery.applyFlagSettings(settings))The ScalaDoc says "Only available in streaming input mode", but there is no guard here. If called outside of streaming input mode the SDK will likely reject it at runtime. A note about the expected failure mode (or wrapping the SDK error with a more descriptive 4. compactSummary = firstString(raw, "compact_summary", "compactSummary").getOrElse(""),If the SDK omits Positives
Missing Tests
These may be hard to test without a live SDK, but if there are mock patterns elsewhere in the test suite they'd be worth adding. Summary: The changes are correct and follow existing conventions. The items above are mostly minor quality/consistency notes. The A2A ordering fix and SDK parity additions look good to merge once the version-pin question is resolved intentionally. |
Summary
compact_summaryfieldsystem/api_retrymessage emitted on retryable API errorsSettingsmid-session (streaming input mode only)'firstParty' | 'bedrock' | 'vertex' | 'foundry')title,displayName,descriptionfields from the bridge'compact'load reason valueallowReadandallowManagedReadPathsOnlyfieldsTest plan
./mill agent.compile— clean compile, no errors./mill agent.test— all tests pass./mill examples.compile— all examples compile🤖 Generated with Claude Code