fix(server): preserve tool lifecycle identity#7151
3 unresolved threads Ā· Jump to file
- apps/server/src/orchestration/Layers/ProviderRuntimeIngestion.ts:219 Ā· <!-- MURMUR_IGNORE --> š” **Medium** `Layers/ProviderRuntimeIngestion.ts:219` For completed or star
- apps/server/src/orchestration/Layers/ProviderRuntimeIngestion.ts:806 Ā· <!-- MURMUR_IGNORE --> š” **Medium** `Layers/ProviderRuntimeIngestion.ts:806` `event.itemId` is sto
- apps/web/src/components/chat/ComposerTasksBadge.tsx:151ā159 Ā· The same "Dismiss tasks for this turn" action is rendered with `Button size="icon-micro" variant="gh
apps/server/src/orchestration/Layers/ProviderRuntimeIngestion.ts Ā· Earlier revision d25f98f1 Ā· right 219
Original diff
@@ -211,6 +211,17 @@ function truncateDetail(value: string, limit = 180): string {
return value.length > limit ? `${value.slice(0, limit - 3)}...` : value;
}
+function withToolCallId(data: unknown, toolCallId: string | undefined): unknown {
+ if (toolCallId === undefined) return data;
+ if (data !== null && typeof data === "object" && !Array.isArray(data)) {
+ return { toolCallId, ...data };
+ }
+ return {š” Medium Layers/ProviderRuntimeIngestion.ts:219
For completed or started lifecycle events whose data is a string, array, or other non-object value, withToolCallId replaces payload.data with { toolCallId, value }, so consumers no longer receive the original value at payload.data. Preserve the original top-level data shape and expose toolCallId separately, rather than wrapping opaque Schema.Unknown payloads.
No longer relevant as of ce306d218e5fd1676ad2bd84979a2d88a6b1dd07
apps/server/src/orchestration/Layers/ProviderRuntimeIngestion.ts Ā· Earlier revision 20324466 Ā· right 806
Original diff
@@ -803,6 +803,7 @@ export function runtimeEventToActivities(
summary: event.payload.title ?? "Tool updated",
payload: {
itemType: event.payload.itemType,
+ ...(event.itemId !== undefined ? { toolCallId: event.itemId } : {}),š” Medium Layers/ProviderRuntimeIngestion.ts:806
event.itemId is stored as top-level payload.toolCallId, but clients only read payload.data.toolCallId, so tool.updated and tool.completed rows whose identity exists only in event.itemId still fall back to title/detail and can fail to fold when those fields change. Store the ID inside data as well, or update the client extractors in the same change.
ā Resolved in 8e450c7309922efdbfeaf7f84b795afea292cc70
apps/web/src/components/chat/ComposerTasksBadge.tsx Ā· Earlier revision 9df356b0 Ā· right 151ā159
Original diff
@@ -148,16 +148,15 @@ export const ComposerTasksBadge = memo(function ComposerTasksBadge({
</span>
<TaskSegments className="w-20" steps={steps} />
</button>
- <Button
- size="icon-micro"
- variant="ghost-muted"
+ <button
+ type="button"
aria-label="Dismiss tasks for this turn"
- className="shrink-0"
+ className="inline-flex size-5 shrink-0 cursor-pointer items-center justify-center rounded-md text-muted-foreground/65 hover:bg-muted/60 hover:text-foreground"
onClick={onDismiss}
onPointerDown={(event) => event.preventDefault()}
>
<XIcon aria-hidden className="size-3" />
- </Button>
+ </button>apps/web/src/components/chat/ComposerTasksBadge.tsx Ā· right 151ā159
The same "Dismiss tasks for this turn" action is rendered with Button size="icon-micro" variant="ghost-muted" in the inline placement above (lines 102-111), but hand-rolled as a raw <button> here and again in ComposerTasksDrawer (lines 191-199). The raw version drops the primitive's focus-visible ring tokens (focus-visible:ring-2 focus-visible:ring-ring ring-offset-*), the coarse-pointer 44px hit target (pointer-coarse:after:min-h-11/min-w-11), and uses rounded-md/hover:bg-muted/60 instead of the shared rounded-sm/hover:bg-accent treatment, so the identical control behaves differently depending on placement. Consider using the primitive in both places (it is already imported):
| 1 | <Button |
| 2 | size="icon-micro" |
| 3 | variant="ghost-muted" |
| 4 | aria-label="Dismiss tasks for this turn" |
| 5 | className="shrink-0" |
| 6 | onClick={onDismiss} |
| 7 | onPointerDown={(event) => event.preventDefault()} |
| 8 | > |
| 9 | <XIcon aria-hidden className="size-3" /> |
| 10 | </Button> |
Posted via Macroscope ā UI Consistency
This thread targets ComposerTasksBadge.tsx from the old stacked diff. PR #7151 now contains only the server lifecycle projection files, so the UI consistency suggestion belongs to the already-merged composer PR and is no longer actionable here.