Skip to content

Commit 36159be

Browse files
authored
Warm start UI (#1882)
* Better trace icon * Better Waitpoint token icon * Fix for bad jsx * Warm and cold start icons * Tooltips now use a <Portal> so they appear on top * Warm start components * Added warm start markers to the Run page and inspector * Fix for getting the correct value from the metadata * Better trace icon, with fallback to a passed in one * Removed unused isWarmStart function
1 parent 7644d92 commit 36159be

File tree

12 files changed

+199
-40
lines changed

12 files changed

+199
-40
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
export function TraceIcon({ className }: { className?: string }) {
2+
return (
3+
<svg className={className} viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
4+
<rect x="2" y="2" width="13" height="6" rx="2" fill="currentColor" />
5+
<rect x="9" y="9" width="13" height="6" rx="2" fill="currentColor" />
6+
<rect x="2" y="16" width="13" height="6" rx="2" fill="currentColor" />
7+
</svg>
8+
);
9+
}

apps/webapp/app/assets/icons/WaitpointTokenIcon.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ export function WaitpointTokenIcon({ className }: { className?: string }) {
44
<path
55
fillRule="evenodd"
66
clipRule="evenodd"
7-
d="M6.71193 3.50338C6.89005 3.1921 7.22123 3.00004 7.57987 3.00003L16.4201 3C16.7787 3 17.1099 3.19206 17.288 3.50334L21.8658 11.5034C22.0419 11.8111 22.0419 12.189 21.8658 12.4967L17.288 20.4967C17.1099 20.8079 16.7787 21 16.4201 21H7.57987C7.22123 21 6.89005 20.8079 6.71193 20.4967L2.1342 12.4967C1.95813 12.189 1.95813 11.8111 2.1342 11.5034L6.71193 3.50338ZM8.5 9.00011C8.5 8.44783 8.94771 8.00011 9.5 8.00011H10C10.5523 8.00011 11 8.44783 11 9.00011V15.0001C11 15.5524 10.5523 16.0001 10 16.0001H9.5C8.94771 16.0001 8.5 15.5524 8.5 15.0001V9.00011ZM14 8.00006C13.4477 8.00006 13 8.44777 13 9.00006V15.0001C13 15.5523 13.4477 16.0001 14 16.0001H14.5C15.0523 16.0001 15.5 15.5523 15.5 15.0001V9.00006C15.5 8.44777 15.0523 8.00006 14.5 8.00006H14Z"
7+
d="M15.1715 2C15.702 1.99999 16.2107 2.21072 16.5858 2.5858L21.4142 7.41435C21.7893 7.78943 22 8.29813 22 8.82855V15.1717C22 15.7021 21.7893 16.2109 21.4142 16.5859L16.5858 21.4144C16.2107 21.7894 15.702 22.0001 15.1716 22.0001H8.82842C8.29798 22.0001 7.78927 21.7894 7.4142 21.4144L2.58578 16.5859C2.21071 16.2109 2 15.7022 2 15.1717V8.82856C2 8.29814 2.21071 7.78943 2.58578 7.41436L7.41422 2.58586C7.78929 2.21079 8.29799 2.00007 8.82842 2.00007L15.1715 2ZM8.49997 9.00007C8.49997 8.44779 8.94769 8.00007 9.49997 8.00007H9.99997C10.5523 8.00007 11 8.44779 11 9.00007V15.0001C11 15.5524 10.5523 16.0001 9.99997 16.0001H9.49997C8.94769 16.0001 8.49997 15.5524 8.49997 15.0001V9.00007ZM14 8.00007C13.4477 8.00007 13 8.44779 13 9.00007V15.0001C13 15.5524 13.4477 16.0001 14 16.0001H14.5C15.0523 16.0001 15.5 15.5524 15.5 15.0001V9.00007C15.5 8.44779 15.0523 8.00007 14.5 8.00007H14Z"
88
fill="currentColor"
99
/>
1010
</svg>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import { FireIcon } from "@heroicons/react/20/solid";
2+
import { cn } from "~/utils/cn";
3+
4+
function ColdStartIcon({ className }: { className?: string }) {
5+
return (
6+
<svg className={className} viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
7+
<path
8+
d="M12.0016 2C12.7127 2 13.2872 2.55859 13.2872 3.25V4.42578L13.8898 3.83984C14.2675 3.47266 14.8782 3.47266 15.2518 3.83984C15.6255 4.20703 15.6295 4.80078 15.2518 5.16406L13.2832 7.07812V9.82422L15.75 8.42578L16.4611 5.84375C16.5977 5.34375 17.1281 5.04688 17.6423 5.17969C18.1566 5.3125 18.4619 5.82813 18.3253 6.32813L18.1164 7.08203L19.0645 6.54297C19.6792 6.19531 20.4667 6.39844 20.8243 6.99219C21.1818 7.58594 20.9769 8.35547 20.3622 8.70313L19.3458 9.28125L20.2176 9.50781C20.7319 9.64062 21.0372 10.1563 20.9006 10.6563C20.764 11.1563 20.2337 11.4531 19.7194 11.3203L16.9995 10.6133L14.5528 12L16.9995 13.3867L19.7194 12.6797C20.2337 12.5469 20.764 12.8437 20.9006 13.3437C21.0372 13.8437 20.7319 14.3594 20.2176 14.4922L19.3458 14.7188L20.3622 15.2969C20.9769 15.6445 21.1818 16.4102 20.8243 17.0078C20.4667 17.6055 19.6792 17.8047 19.0645 17.457L18.1164 16.918L18.3253 17.6719C18.4619 18.1719 18.1566 18.6875 17.6423 18.8203C17.1281 18.9531 16.5977 18.6563 16.4611 18.1563L15.75 15.5742L13.2872 14.1758V16.9219L15.2558 18.8359C15.6335 19.2031 15.6335 19.7969 15.2558 20.1602C14.8782 20.5234 14.2675 20.5273 13.8939 20.1602L13.2912 19.5742V20.75C13.2912 21.4414 12.7167 22 12.0056 22C11.2945 22 10.7199 21.4414 10.7199 20.75V19.5742L10.1173 20.1602C9.73964 20.5273 9.12896 20.5273 8.75532 20.1602C8.38169 19.793 8.37767 19.1992 8.75532 18.8359L10.724 16.9219V14.1758L8.25714 15.5742L7.54602 18.1563C7.40942 18.6563 6.87909 18.9531 6.36484 18.8203C5.85058 18.6875 5.54524 18.1719 5.68184 17.6719L5.89076 16.918L4.93456 17.4531C4.31987 17.8008 3.53241 17.5977 3.17485 17.0039C2.81728 16.4102 3.02619 15.6406 3.63687 15.293L4.65333 14.7148L3.78151 14.4883C3.26725 14.3555 2.96191 13.8398 3.09851 13.3398C3.23511 12.8398 3.76544 12.543 4.27969 12.6758L6.99962 13.3828L9.45037 12L7.00364 10.6133L4.28371 11.3203C3.76945 11.4531 3.23913 11.1563 3.10253 10.6563C2.96593 10.1563 3.27127 9.64062 3.78552 9.50781L4.65735 9.28125L3.64089 8.70313C3.02619 8.35547 2.82129 7.58984 3.17886 6.99609C3.53643 6.40234 4.32389 6.19922 4.93858 6.54688L5.88674 7.08594L5.67783 6.33203C5.54123 5.83203 5.84657 5.31641 6.36082 5.18359C6.87508 5.05078 7.4054 5.34766 7.542 5.84766L8.25312 8.42969L10.7159 9.82422V7.07812L8.74729 5.16406C8.36963 4.79688 8.36963 4.20312 8.74729 3.83984C9.12495 3.47656 9.73562 3.47266 10.1093 3.83984L10.7119 4.42578L10.7159 3.25C10.7159 2.55859 11.2904 2 12.0016 2Z"
9+
fill="currentColor"
10+
/>
11+
</svg>
12+
);
13+
}
14+
15+
export function WarmStartIcon({
16+
isWarmStart,
17+
className,
18+
}: {
19+
isWarmStart: boolean;
20+
className?: string;
21+
}) {
22+
if (isWarmStart) {
23+
return <FireIcon className={cn("text-orange-400", className)} />;
24+
}
25+
return <ColdStartIcon className={cn("text-blue-400", className)} />;
26+
}
+59
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
import { WarmStartIcon } from "~/assets/icons/WarmStartIcon";
2+
import { InfoIconTooltip, SimpleTooltip } from "./primitives/Tooltip";
3+
import { cn } from "~/utils/cn";
4+
import { Paragraph } from "./primitives/Paragraph";
5+
6+
export function WarmStartCombo({
7+
isWarmStart,
8+
showTooltip = false,
9+
className,
10+
}: {
11+
isWarmStart: boolean;
12+
showTooltip?: boolean;
13+
className?: string;
14+
}) {
15+
return (
16+
<div className={cn("flex items-center gap-1 text-sm text-text-dimmed", className)}>
17+
<WarmStartIcon isWarmStart={isWarmStart} className="size-5" />
18+
<span>{isWarmStart ? "Warm Start" : "Cold Start"}</span>
19+
{showTooltip && <InfoIconTooltip content={<WarmStartTooltipContent />} />}
20+
</div>
21+
);
22+
}
23+
24+
export function WarmStartIconWithTooltip({
25+
isWarmStart,
26+
className,
27+
}: {
28+
isWarmStart: boolean;
29+
className?: string;
30+
}) {
31+
return (
32+
<SimpleTooltip
33+
className="relative z-[9999]"
34+
button={<WarmStartIcon isWarmStart={isWarmStart} className={className} />}
35+
content={<WarmStartTooltipContent />}
36+
/>
37+
);
38+
}
39+
40+
function WarmStartTooltipContent() {
41+
return (
42+
<div className="flex max-w-xs flex-col gap-4 p-1">
43+
<div>
44+
<WarmStartCombo isWarmStart={false} className="mb-0.5 text-text-bright" />
45+
<Paragraph variant="small" className="!text-wrap text-text-dimmed">
46+
A cold start happens when we need to boot up a new machine for your run to execute. This
47+
takes longer than a warm start.
48+
</Paragraph>
49+
</div>
50+
<div>
51+
<WarmStartCombo isWarmStart={true} className="mb-0.5 text-text-bright" />
52+
<Paragraph variant="small" className="!text-wrap text-text-dimmed">
53+
A warm start happens when we can reuse a machine from a run that recently finished. This
54+
takes less time than a cold start.
55+
</Paragraph>
56+
</div>
57+
</div>
58+
);
59+
}

apps/webapp/app/components/primitives/Tooltip.tsx

+12-10
Original file line numberDiff line numberDiff line change
@@ -37,16 +37,18 @@ const TooltipContent = React.forwardRef<
3737
React.ElementRef<typeof TooltipPrimitive.Content>,
3838
TooltipContentProps
3939
>(({ className, sideOffset = 4, variant = "basic", ...props }, ref) => (
40-
<TooltipPrimitive.Content
41-
ref={ref}
42-
sideOffset={sideOffset}
43-
className={cn(
44-
"z-50 overflow-hidden animate-in data-[side=bottom]:slide-in-from-top-1 data-[side=left]:slide-in-from-right-1 data-[side=right]:slide-in-from-left-1 data-[side=top]:slide-in-from-bottom-1 focus-visible:outline-none",
45-
variantClasses[variant],
46-
className
47-
)}
48-
{...props}
49-
/>
40+
<TooltipPrimitive.Portal>
41+
<TooltipPrimitive.Content
42+
ref={ref}
43+
sideOffset={sideOffset}
44+
className={cn(
45+
"z-50 overflow-hidden animate-in data-[side=bottom]:slide-in-from-top-1 data-[side=left]:slide-in-from-right-1 data-[side=right]:slide-in-from-left-1 data-[side=top]:slide-in-from-bottom-1 focus-visible:outline-none",
46+
variantClasses[variant],
47+
className
48+
)}
49+
{...props}
50+
/>
51+
</TooltipPrimitive.Portal>
5052
));
5153
TooltipContent.displayName = TooltipPrimitive.Content.displayName;
5254

apps/webapp/app/components/runs/v3/RunIcon.tsx

+2-1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import { MiddlewareIcon } from "~/assets/icons/MiddlewareIcon";
1818
import { FunctionIcon } from "~/assets/icons/FunctionIcon";
1919
import { TriggerIcon } from "~/assets/icons/TriggerIcon";
2020
import { PythonLogoIcon } from "~/assets/icons/PythonLogoIcon";
21+
import { TraceIcon } from "~/assets/icons/TraceIcon";
2122

2223
type TaskIconProps = {
2324
name: string | undefined;
@@ -65,7 +66,7 @@ export function RunIcon({ name, className, spanName }: TaskIconProps) {
6566
case "wait":
6667
return <PauseIcon className={cn(className, "text-teal-500")} />;
6768
case "trace":
68-
return <Squares2X2Icon className={cn(className, "text-text-dimmed")} />;
69+
return <TraceIcon className={cn(className, "text-text-dimmed")} />;
6970
case "tag":
7071
return <TagIcon className={cn(className, "text-text-dimmed")} />;
7172
case "queue":

apps/webapp/app/presenters/v3/SpanPresenter.server.ts

+19-2
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,13 @@ import {
22
isWaitpointOutputTimeout,
33
type MachinePresetName,
44
prettyPrintPacket,
5+
SemanticInternalAttributes,
56
TaskRunError,
67
} from "@trigger.dev/core/v3";
78
import { getMaxDuration } from "@trigger.dev/core/v3/isomorphic";
89
import { RUNNING_STATUSES } from "~/components/runs/v3/TaskRunStatus";
910
import { logger } from "~/services/logger.server";
10-
import { eventRepository } from "~/v3/eventRepository.server";
11+
import { eventRepository, rehydrateAttribute } from "~/v3/eventRepository.server";
1112
import { machinePresetFromName } from "~/v3/machinePresets.server";
1213
import { getTaskEventStoreTableForRun, type TaskEventStoreTable } from "~/v3/taskEventStore.server";
1314
import { isFailedRunStatus, isFinalRunStatus } from "~/v3/taskStatus";
@@ -455,7 +456,7 @@ export class SpanPresenter extends BasePresenter {
455456
};
456457

457458
switch (span.entity.type) {
458-
case "waitpoint":
459+
case "waitpoint": {
459460
if (!span.entity.id) {
460461
logger.error(`SpanPresenter: No waitpoint id`, {
461462
spanId,
@@ -486,7 +487,23 @@ export class SpanPresenter extends BasePresenter {
486487
object: waitpoint,
487488
},
488489
};
490+
}
491+
case "attempt": {
492+
const isWarmStart = rehydrateAttribute<boolean>(
493+
span.metadata,
494+
SemanticInternalAttributes.WARM_START
495+
);
489496

497+
return {
498+
...data,
499+
entity: {
500+
type: "attempt" as const,
501+
object: {
502+
isWarmStart,
503+
},
504+
},
505+
};
506+
}
490507
default:
491508
return { ...data, entity: null };
492509
}

apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.runs.$runParam/route.tsx

+11-12
Original file line numberDiff line numberDiff line change
@@ -21,23 +21,18 @@ import {
2121
tryCatch,
2222
} from "@trigger.dev/core/v3";
2323
import { type RuntimeEnvironmentType } from "@trigger.dev/database";
24-
import { AnimatePresence, motion } from "framer-motion";
24+
import { motion } from "framer-motion";
2525
import { useCallback, useEffect, useRef, useState } from "react";
2626
import { useHotkeys } from "react-hotkeys-hook";
27-
import { DisconnectedIcon } from "~/assets/icons/ConnectionIcons";
27+
import { redirect } from "remix-typedjson";
2828
import { ShowParentIcon, ShowParentIconSelected } from "~/assets/icons/ShowParentIcon";
2929
import tileBgPath from "~/assets/images/[email protected]";
30-
import {
31-
DevDisconnectedBanner,
32-
useCrossEngineIsConnected,
33-
useDevPresence,
34-
} from "~/components/DevPresence";
30+
import { DevDisconnectedBanner, useCrossEngineIsConnected } from "~/components/DevPresence";
31+
import { WarmStartIconWithTooltip } from "~/components/WarmStarts";
3532
import { AdminDebugTooltip } from "~/components/admin/debugTooltip";
3633
import { PageBody } from "~/components/layout/AppLayout";
3734
import { Badge } from "~/components/primitives/Badge";
3835
import { Button, LinkButton } from "~/components/primitives/Buttons";
39-
import { Callout } from "~/components/primitives/Callout";
40-
import { ClipboardField } from "~/components/primitives/ClipboardField";
4136
import { DateTimeShort } from "~/components/primitives/DateTime";
4237
import { Dialog, DialogTrigger } from "~/components/primitives/Dialog";
4338
import { Header3 } from "~/components/primitives/Headers";
@@ -100,8 +95,6 @@ import {
10095
} from "~/utils/pathBuilder";
10196
import { useCurrentPlan } from "../_app.orgs.$organizationSlug/route";
10297
import { SpanView } from "../resources.orgs.$organizationSlug.projects.$projectParam.env.$envParam.runs.$runParam.spans.$spanParam/route";
103-
import { redirectWithErrorMessage } from "~/models/message.server";
104-
import { redirect } from "remix-typedjson";
10598

10699
const resizableSettings = {
107100
parent: {
@@ -1045,7 +1038,13 @@ function NodeText({ node }: { node: TraceEvent }) {
10451038

10461039
function NodeStatusIcon({ node }: { node: TraceEvent }) {
10471040
if (node.data.level !== "TRACE") return null;
1048-
if (node.data.style.variant !== "primary") return null;
1041+
if (!node.data.style.variant) return null;
1042+
1043+
if (node.data.style.variant === "warm") {
1044+
return <WarmStartIconWithTooltip isWarmStart={true} className="size-4" />;
1045+
} else if (node.data.style.variant === "cold") {
1046+
return <WarmStartIconWithTooltip isWarmStart={false} className="size-4" />;
1047+
}
10491048

10501049
if (node.data.isCancelled) {
10511050
return (

apps/webapp/app/routes/resources.orgs.$organizationSlug.projects.$projectParam.env.$envParam.runs.$runParam.spans.$spanParam/route.tsx

+41-11
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,13 @@ import {
44
EnvelopeIcon,
55
QueueListIcon,
66
} from "@heroicons/react/20/solid";
7-
import { Link } from "@remix-run/react";
87
import { type LoaderFunctionArgs } from "@remix-run/server-runtime";
98
import {
109
formatDurationMilliseconds,
1110
type TaskRunError,
1211
taskRunErrorEnhancer,
1312
} from "@trigger.dev/core/v3";
13+
import { assertNever } from "assert-never";
1414
import { useEffect } from "react";
1515
import { typedjson, useTypedFetcher } from "remix-typedjson";
1616
import { ExitIcon } from "~/assets/icons/ExitIcon";
@@ -37,20 +37,23 @@ import { TabButton, TabContainer } from "~/components/primitives/Tabs";
3737
import { TextLink } from "~/components/primitives/TextLink";
3838
import { InfoIconTooltip, SimpleTooltip } from "~/components/primitives/Tooltip";
3939
import { RunTimeline, RunTimelineEvent, SpanTimeline } from "~/components/run/RunTimeline";
40+
import { PacketDisplay } from "~/components/runs/v3/PacketDisplay";
4041
import { RunIcon } from "~/components/runs/v3/RunIcon";
4142
import { RunTag } from "~/components/runs/v3/RunTag";
4243
import { SpanEvents } from "~/components/runs/v3/SpanEvents";
4344
import { SpanTitle } from "~/components/runs/v3/SpanTitle";
4445
import { TaskRunAttemptStatusCombo } from "~/components/runs/v3/TaskRunAttemptStatus";
4546
import { TaskRunStatusCombo, TaskRunStatusReason } from "~/components/runs/v3/TaskRunStatus";
47+
import { WaitpointDetailTable } from "~/components/runs/v3/WaitpointDetails";
48+
import { WarmStartCombo } from "~/components/WarmStarts";
49+
import { useEnvironment } from "~/hooks/useEnvironment";
4650
import { useOrganization } from "~/hooks/useOrganizations";
4751
import { useProject } from "~/hooks/useProject";
4852
import { useSearchParams } from "~/hooks/useSearchParam";
4953
import { useHasAdminAccess } from "~/hooks/useUser";
5054
import { redirectWithErrorMessage } from "~/models/message.server";
5155
import { type Span, SpanPresenter, type SpanRun } from "~/presenters/v3/SpanPresenter.server";
5256
import { logger } from "~/services/logger.server";
53-
import { requireUserId } from "~/services/session.server";
5457
import { cn } from "~/utils/cn";
5558
import { formatCurrencyAccurate } from "~/utils/numberFormatter";
5659
import {
@@ -63,15 +66,8 @@ import {
6366
v3SchedulePath,
6467
v3SpanParamsSchema,
6568
} from "~/utils/pathBuilder";
66-
import {
67-
CompleteWaitpointForm,
68-
ForceTimeout,
69-
} from "../resources.orgs.$organizationSlug.projects.$projectParam.env.$envParam.waitpoints.$waitpointFriendlyId.complete/route";
70-
import { useEnvironment } from "~/hooks/useEnvironment";
71-
import { WaitpointStatusCombo } from "~/components/runs/v3/WaitpointStatus";
72-
import { PacketDisplay } from "~/components/runs/v3/PacketDisplay";
73-
import { WaitpointDetailTable } from "~/components/runs/v3/WaitpointDetails";
7469
import { createTimelineSpanEventsFromSpanEvents } from "~/utils/timelineSpanEvents";
70+
import { CompleteWaitpointForm } from "../resources.orgs.$organizationSlug.projects.$projectParam.env.$envParam.waitpoints.$waitpointFriendlyId.complete/route";
7571

7672
export const loader = async ({ request, params }: LoaderFunctionArgs) => {
7773
const { projectParam, organizationSlug, envParam, runParam, spanParam } =
@@ -935,6 +931,40 @@ function SpanEntity({ span }: { span: Span }) {
935931
}
936932

937933
switch (span.entity.type) {
934+
case "attempt": {
935+
return (
936+
<div className="flex flex-col gap-4 p-3">
937+
<div className="border-b border-grid-bright pb-3">
938+
<TaskRunAttemptStatusCombo
939+
status={
940+
span.isCancelled
941+
? "CANCELED"
942+
: span.isError
943+
? "FAILED"
944+
: span.isPartial
945+
? "EXECUTING"
946+
: "COMPLETED"
947+
}
948+
className="text-sm"
949+
/>
950+
</div>
951+
<SpanTimeline
952+
startTime={new Date(span.startTime)}
953+
duration={span.duration}
954+
inProgress={span.isPartial}
955+
isError={span.isError}
956+
events={createTimelineSpanEventsFromSpanEvents(span.events, isAdmin)}
957+
/>
958+
{span.entity.object.isWarmStart !== undefined ? (
959+
<WarmStartCombo
960+
isWarmStart={span.entity.object.isWarmStart}
961+
showTooltip
962+
className="mt-3"
963+
/>
964+
) : null}
965+
</div>
966+
);
967+
}
938968
case "waitpoint": {
939969
return (
940970
<div className="grid h-full grid-rows-[1fr_auto]">
@@ -957,7 +987,7 @@ function SpanEntity({ span }: { span: Span }) {
957987
);
958988
}
959989
default: {
960-
return <Paragraph variant="small">No span for {span.entity.type}</Paragraph>;
990+
assertNever(span.entity);
961991
}
962992
}
963993
}

apps/webapp/app/v3/eventRepository.server.ts

+4-2
Original file line numberDiff line numberDiff line change
@@ -1638,7 +1638,7 @@ function rehydrateShow(properties: Prisma.JsonValue): { actions?: boolean } | un
16381638
return;
16391639
}
16401640

1641-
function rehydrateAttribute<T extends AttributeValue>(
1641+
export function rehydrateAttribute<T extends AttributeValue>(
16421642
properties: Prisma.JsonValue,
16431643
key: string
16441644
): T | undefined {
@@ -1656,7 +1656,9 @@ function rehydrateAttribute<T extends AttributeValue>(
16561656

16571657
const value = properties[key];
16581658

1659-
if (!value) return;
1659+
if (value === undefined) {
1660+
return;
1661+
}
16601662

16611663
return value as T;
16621664
}

packages/core/src/v3/logger/taskLogger.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ export class OtelTaskLogger implements TaskLogger {
9999
...options,
100100
attributes: {
101101
...options?.attributes,
102-
...(options?.icon ? { [SemanticInternalAttributes.STYLE_ICON]: options.icon } : {}),
102+
[SemanticInternalAttributes.STYLE_ICON]: options?.icon ?? "trace",
103103
},
104104
};
105105

0 commit comments

Comments
 (0)