Repository navigation
BF-2441: iOS photo previews, drop snippet chips, show Muse Code subagents - #1742
Conversation
Photos in the composer use the attached picture. Chips that only paste a sentence are gone. Child and in-progress steps stay visible when the transcript already has them. Co-authored-by: Jay Wedgeworth <jaywedgeworth22@users.noreply.github.com>
This comment has been minimized.
This comment has been minimized.
|
Automatic approval held Kody's assessment:
|
|
[GB-DESIGNER 📁BF]
|
Done and Failed are only those outcomes. Cancelled or stopped reads as Stopped. Composer photos downsample off the main thread, and a canned title no longer hides a custom prompt. Co-authored-by: Jay Wedgeworth <jaywedgeworth22@users.noreply.github.com>
This comment has been minimized.
This comment has been minimized.
PendingAttachmentGlyph clears the chip when item.id changes and ignores decode results whose identity no longer matches the row. ComposerPendingThumbnailCache decodes with a cancellable off-main wait, records strip removals, and skips cache writes after cancellation or removal. CompanionCore tests cover the policy and cache. Co-authored-by: Jay Wedgeworth <jaywedgeworth22@users.noreply.github.com>
This comment has been minimized.
This comment has been minimized.
Dropping removedIds.clear from thumbnail load stops a remove during decode from being erased by a late task start. reinstate runs when replacePendingAttachments keeps an id, and the decode race test yields to removal before asserting. Co-authored-by: Jay Wedgeworth <jaywedgeworth22@users.noreply.github.com>
CacheGate holds one lock across the removal check and NSCache write. Tombstones track in-flight decodes, clear when a decode finishes, and prune with replacePendingAttachments; the cap matches twice the 16-entry image cache. Co-authored-by: Jay Wedgeworth <jaywedgeworth22@users.noreply.github.com>
This comment has been minimized.
This comment has been minimized.
Per-id decode refcounts keep tombstones and prune guards until the last overlapping decode ends. shouldStoreThumbnailInCache now runs inside the cache gate lock with the live tombstone set. Co-authored-by: Jay Wedgeworth <jaywedgeworth22@users.noreply.github.com>
This comment has been minimized.
This comment has been minimized.
Co-authored-by: Jay Wedgeworth <jaywedgeworth22@users.noreply.github.com>
This comment has been minimized.
This comment has been minimized.
| Autofix run https://github.com/Simple-With-Us/BotFleet/actions/runs/43009838922 started for `sentry[bot]`'s tagged request. Owner/sentry request: exempt from the per-bot cap (owner rule 2026-10-20). |
Failed-send recovery now calls replacePendingAttachments(outgoing) so restored chips clear thumbnail tombstones, matching the queued-edit path. Co-authored-by: Jay Wedgeworth <jaywedgeworth22@users.noreply.github.com>
This comment has been minimized.
This comment has been minimized.
Re-apply remove after the tombstoned decode so endDecode cannot substitute for reinstate before the success assertions. Co-authored-by: Jay Wedgeworth <jaywedgeworth22@users.noreply.github.com>
Kody Review CompleteGreat news! 🎉 Keep up the excellent work! 🚀 Kody Guide: Usage and ConfigurationInteracting with Kody
Current Kody ConfigurationReview OptionsThe following review options are enabled or disabled:
Automatic approval held: Complex iOS UI and concurrency change with unverified runtime: off-main thumbnail cache with tombstone gating has open race findings, plus receipt status and activity folding semantics in historically bug-prone files; needs human review. |
Issue: BF-2441.
The receipt treats the words failed and failure as Failed. BF-2440 stays open. A card still shows Failed when the stored outcome is false, including when the detail text says the child finished.
Kody's three findings on
e3b76a76are fixed in4b8918dc, and the review threads are left open. Done is only an explicit success. Failed is only a failure or an error. Cancelled or stopped reads as Stopped, and pending, empty, or unknown stays Running. Composer photo chips downsample with ImageIO off the main thread. The thumbnail cache has count and cost limits and drops an entry when the attachment leaves the strip. A chip is suppressed for a canned title only when its prompt is empty or is one of the canned prompts.This VM cannot run Swift. The CompanionCore tests, the unsigned iOS build, the receipt badge, the photo chip, and the remove button were not runtime-verified here. CI is the check for the tests and the build.
Summary
Implements BF-2441 for iOS chat composer and activity transcript. Pending image attachments now show a photo thumbnail in the draft strip, with file or undecodable-image fallback to a system icon. Empty-composer snippet chips that only paste a canned sentence are removed, while
/slash commands are preserved. Tool subagent child steps are shown as indented rows and kept out of folded activity runs, with run wording changed from Complete to Done.Changes
previewImageDatafor displayable images and render a 36pt thumbnail viaPendingAttachmentGlyphwithNSCachereuse. Draft strip layout adjusts padding and minimum height.ComposerPromptChips.isCannedSnippet, covering prior Show diff, Run tests, Explain steps and What's next prompts. Slash-prefixed prompts are exempted.itemIdandparentItemIdto model parent-child steps. NewToolStepStatusmaps outcome to Done, Running or Failed with corresponding receipt status. Receipt status parsing is case-insensitive and acceptsin_progressandfailed/failurevariants.ChildStepInset. Running steps and child steps are excluded from folded activity runs and message-run grouping.Tests added
Adds
ComposerPromptChipsTestsfor canned-snippet rejection and slash-command exemption. AddsActivityRunsTestscases for running steps staying unfolded, child steps staying on their own row, and decoding of parent linkage and status mapping. AddsMessageGroupingTestscoverage for running and child steps staying visible. AddsChatAttachmentTestscoverage for image preview bytes, non-displayable format, file and empty payload handling. No test-run results, device verification, deployment or approval status is reported in the changes, so runtime behavior remains unverified.Open review findings
The three medium findings on unknown receipt status, main-thread thumbnail decode, and title-only chip suppression are addressed in the follow-up commit. Threads stay open until review.
BF-2441: iOS photo previews, snippet chips, and skill receipt status.
Summary
Updates iOS chat composer and skill receipts for correctness and performance. Photo attachments now render efficient thumbnails, canned prompt chips no longer hide custom prompts, and cancelled tool calls no longer read as Done.
Changes
SkillReceiptStatusin CompanionCore. Only success reads as Done, only error/failure reads as Failed, cancelled/canceled/stopped reads as neutral Stopped, and pending/empty/unknown stays Running. Receipt badge, icon, and border updated to match.Tests
Added
SkillReceiptStatusTestscovering success, failure, stopped, and running mappings, and extendedComposerPromptChipsTestsfor custom prompts and empty-prompt cases. No test-run results, deployment, or runtime verification reported.Risks / Open review findings
Automated review reported 2 medium findings, unverified as resolved: reused attachment glyph may show a stale thumbnail, and thumbnail decode work may continue after removal wasting CPU. Thumbnail cache eviction and off-main decode behavior otherwise unverified in production.
Resolves BF-2441 for iOS composer photo previews. Moves pending-attachment thumbnail caching out of
ChatViewinto sharedComposerPendingThumbnailCachewithComposerThumbnailCachePolicygating UI and cache updates.Changes
Tests added
ComposerPendingThumbnailCacheTestsfor chip-size downsampling, cache reuse, eviction on remove, removal during decode, and cancelled-task behavior. AddsComposerThumbnailCachePolicyTestsfor stale row identity and removed-attachment store decisions. Run results were not reported in the changes, so passing status is unverified.Open risks
ComposerPendingThumbnailCache.swift: possible race between removal check and cache store, and unbounded growth of removed-ID tracking for app lifetime. Resolution is unverified.Summary
BF-2441 iOS composer photo preview hardening: reworks
ComposerPendingThumbnailCacheto correctly handle remove and re-add of pending photo attachments. Late decodes no longer repopulate thumbnails for attachments dropped from the strip, reinstated strip items can load again, and removal tombstones are pruned and capped to bound growth. Additional scope implied by the title such as snippet chips and Muse Code subagents is not visible in this diff and remains unverified.Changes
ChatView.swift: after syncingpendingAttachments, prunes tombstones not in the kept set and reinstates tombstones for current strip items.ComposerPendingThumbnailCache.swift: replaces simple removed-ID set with gatedCacheGatetrackingremovedIdsand in-flight decodes, withremove,reinstate,pruneTombstones, gatedstore, decode begin/end tracking, andtombstoneLimitof 32.Tests
testReinstateLetsAThumbLoadAgainAfterReplacement,testManyRemovesStayWithinTheTombstoneCap,testPruneDropsTombstonesThatNoLongerGuardAStripId, andtestDecodeCompletionClearsItsTombstone; updatedtestRemoveDuringDecodeDoesNotPopulateCacheto race decode against removal. Test execution results were not provided in the diff and remain unverified.Open risks
droppedFromStripas false with gating moved tostore, and concurrent duplicate decodes may clear in-flight state early. No resolution or runtime verification is evidenced in the diff.Summary
Addresses BF-2441 for iOS photo previews by hardening the composer pending thumbnail cache against overlapping decodes. Consolidates the store eligibility check inside the cache gate so cancellation and strip-removal are evaluated at store time. Replaces the in-flight decode set with per-attachment reference counts so removal tombstones are retained until the last decode ends.
Changes
ComposerThumbnailCachePolicy.shouldStoreThumbnailInCacheevaluation intoCacheGate.store.inFlightDecodestracking todecodeCountswith updated prune, end-decode, and tombstone-cap logic.Tests
Added
testOverlappingDecodesKeepGuardsUntilTheLastOneEndsto verify tombstone retention across overlapping decodes and cleanup after the final decode. No run results, deployment, or runtime verification reported in the provided changes.Related to BF-2441. Updates
ComposerPendingThumbnailCacheTeststo callinFlightDecodeCountForTests(id:)with the correct argument label. No production code is modified in the provided change, so no user-visible or operational impact is verified.Summary
BF-2441: Fix iOS photo previews on failed-send restore. Restores outgoing pending attachments via
replacePendingAttachmentsso thumbnail cache state is reset correctly.Changes
ChatViewrestore path to callreplacePendingAttachments(outgoing)instead of direct assignment when pending attachments are empty.testAFailedSendRestoreMustReinstateBeforeThumbnailsCachecovering thumbnail regeneration after reinstate.User impact
Pending photo attachments should show previews again after a failed send is restored. Reload behavior is unverified in the provided changes.
Tests
Risks
ComposerPendingThumbnailCacheTests.swift:63: restore test may clear tombstone before reinstate, giving a false pass.Summary
Updates
testAFailedSendRestoreMustReinstateBeforeThumbnailsCacheinComposerPendingThumbnailCacheTeststo explicitly verify thumbnail gating for failed-send restore (BF-2441). Blocked state now assertsthumbnail(for:)returns nil with no cached entry, and restored state asserts it returns a thumbnail with a cached entry.Impact
The provided patch changes test-only logic; user-visible impact is unverified. It tightens coverage for pending-attachment thumbnail reinstatement after a failed send.
Testing
Test logic updated as described; no test run results were reported in the provided context. Automated code review reported no issues in the reviewed changes.