@shipfox/client-workflows 15.0.0 → 17.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.storybook/preview.css +4 -0
- package/.turbo/turbo-build.log +1 -1
- package/.turbo/turbo-type.log +1 -0
- package/CHANGELOG.md +41 -0
- package/dist/components/identifier/identifier.js +2 -2
- package/dist/components/identifier/identifier.js.map +1 -1
- package/dist/components/job-detail/agent-config-failure-callout.d.ts.map +1 -1
- package/dist/components/job-detail/agent-config-failure-callout.js +1 -1
- package/dist/components/job-detail/agent-config-failure-callout.js.map +1 -1
- package/dist/components/job-detail/job-context-panel.d.ts +6 -0
- package/dist/components/job-detail/job-context-panel.d.ts.map +1 -0
- package/dist/components/job-detail/job-context-panel.js +224 -0
- package/dist/components/job-detail/job-context-panel.js.map +1 -0
- package/dist/components/job-detail/job-detail-header.d.ts +10 -1
- package/dist/components/job-detail/job-detail-header.d.ts.map +1 -1
- package/dist/components/job-detail/job-detail-header.js +58 -39
- package/dist/components/job-detail/job-detail-header.js.map +1 -1
- package/dist/components/job-detail/job-detail-view.d.ts +1 -1
- package/dist/components/job-detail/job-detail-view.d.ts.map +1 -1
- package/dist/components/job-detail/job-detail-view.js +92 -41
- package/dist/components/job-detail/job-detail-view.js.map +1 -1
- package/dist/components/job-detail/job-empty-states.d.ts.map +1 -1
- package/dist/components/job-detail/job-empty-states.js +19 -10
- package/dist/components/job-detail/job-empty-states.js.map +1 -1
- package/dist/components/job-detail/job-execution-switcher.js +4 -4
- package/dist/components/job-detail/job-execution-switcher.js.map +1 -1
- package/dist/components/job-detail/json-code.d.ts +14 -0
- package/dist/components/job-detail/json-code.d.ts.map +1 -0
- package/dist/components/job-detail/json-code.js +93 -0
- package/dist/components/job-detail/json-code.js.map +1 -0
- package/dist/components/job-detail/step-attempt-log-panel.d.ts.map +1 -1
- package/dist/components/job-detail/step-attempt-log-panel.js +9 -6
- package/dist/components/job-detail/step-attempt-log-panel.js.map +1 -1
- package/dist/components/job-detail/step-troubleshooting.d.ts +18 -0
- package/dist/components/job-detail/step-troubleshooting.d.ts.map +1 -0
- package/dist/components/job-detail/step-troubleshooting.js +493 -0
- package/dist/components/job-detail/step-troubleshooting.js.map +1 -0
- package/dist/components/job-graph/job-graph-content.d.ts.map +1 -1
- package/dist/components/job-graph/job-graph-content.js +5 -4
- package/dist/components/job-graph/job-graph-content.js.map +1 -1
- package/dist/components/job-graph/job-node.js +3 -3
- package/dist/components/job-graph/job-node.js.map +1 -1
- package/dist/components/step-list/index.d.ts +1 -0
- package/dist/components/step-list/index.d.ts.map +1 -1
- package/dist/components/step-list/index.js.map +1 -1
- package/dist/components/step-list/step-list-model.d.ts.map +1 -1
- package/dist/components/step-list/step-list-model.js +5 -0
- package/dist/components/step-list/step-list-model.js.map +1 -1
- package/dist/components/step-list/step-list.d.ts +5 -1
- package/dist/components/step-list/step-list.d.ts.map +1 -1
- package/dist/components/step-list/step-list.js +117 -82
- package/dist/components/step-list/step-list.js.map +1 -1
- package/dist/components/workflow-run-duration-label.js +1 -1
- package/dist/components/workflow-run-duration-label.js.map +1 -1
- package/dist/components/workflow-run-list/job-status-strip.js +6 -6
- package/dist/components/workflow-run-list/job-status-strip.js.map +1 -1
- package/dist/components/workflow-run-list/workflow-run-filter-menu.js +1 -1
- package/dist/components/workflow-run-list/workflow-run-filter-menu.js.map +1 -1
- package/dist/components/workflow-run-list/workflow-run-filters.js +4 -4
- package/dist/components/workflow-run-list/workflow-run-filters.js.map +1 -1
- package/dist/components/workflow-run-list/workflow-run-list-states.js +6 -6
- package/dist/components/workflow-run-list/workflow-run-list-states.js.map +1 -1
- package/dist/components/workflow-run-list/workflow-run-list-view.js +1 -1
- package/dist/components/workflow-run-list/workflow-run-list-view.js.map +1 -1
- package/dist/components/workflow-run-list/workflow-run-row.js +7 -7
- package/dist/components/workflow-run-list/workflow-run-row.js.map +1 -1
- package/dist/components/workflow-run-summary/workflow-run-attempt-switcher.js +1 -1
- package/dist/components/workflow-run-summary/workflow-run-attempt-switcher.js.map +1 -1
- package/dist/components/workflow-run-summary/workflow-run-summary.d.ts +0 -1
- package/dist/components/workflow-run-summary/workflow-run-summary.d.ts.map +1 -1
- package/dist/components/workflow-run-summary/workflow-run-summary.js +9 -13
- package/dist/components/workflow-run-summary/workflow-run-summary.js.map +1 -1
- package/dist/components/workflow-run-tabs/index.d.ts +3 -0
- package/dist/components/workflow-run-tabs/index.d.ts.map +1 -1
- package/dist/components/workflow-run-tabs/index.js +3 -0
- package/dist/components/workflow-run-tabs/index.js.map +1 -1
- package/dist/components/workflow-run-tabs/run-annotation-count-chip.d.ts +16 -0
- package/dist/components/workflow-run-tabs/run-annotation-count-chip.d.ts.map +1 -0
- package/dist/components/workflow-run-tabs/run-annotation-count-chip.js +50 -0
- package/dist/components/workflow-run-tabs/run-annotation-count-chip.js.map +1 -0
- package/dist/components/workflow-run-tabs/run-annotation-item.d.ts +20 -0
- package/dist/components/workflow-run-tabs/run-annotation-item.d.ts.map +1 -0
- package/dist/components/workflow-run-tabs/run-annotation-item.js +102 -0
- package/dist/components/workflow-run-tabs/run-annotation-item.js.map +1 -0
- package/dist/components/workflow-run-tabs/run-annotation-list.d.ts +39 -0
- package/dist/components/workflow-run-tabs/run-annotation-list.d.ts.map +1 -0
- package/dist/components/workflow-run-tabs/run-annotation-list.js +211 -0
- package/dist/components/workflow-run-tabs/run-annotation-list.js.map +1 -0
- package/dist/components/workflow-run-tabs/run-annotation-summary-line.d.ts +1 -1
- package/dist/components/workflow-run-tabs/run-annotation-summary-line.d.ts.map +1 -1
- package/dist/components/workflow-run-tabs/run-annotation-summary-line.js +90 -25
- package/dist/components/workflow-run-tabs/run-annotation-summary-line.js.map +1 -1
- package/dist/components/workflow-run-tabs/severity-visuals.d.ts +20 -0
- package/dist/components/workflow-run-tabs/severity-visuals.d.ts.map +1 -0
- package/dist/components/workflow-run-tabs/severity-visuals.js +31 -0
- package/dist/components/workflow-run-tabs/severity-visuals.js.map +1 -0
- package/dist/components/workflow-run-view/run-workspace-nav.d.ts +1 -1
- package/dist/components/workflow-run-view/run-workspace-nav.d.ts.map +1 -1
- package/dist/components/workflow-run-view/run-workspace-nav.js +16 -10
- package/dist/components/workflow-run-view/run-workspace-nav.js.map +1 -1
- package/dist/components/workflow-run-view/workflow-run-states.js +6 -6
- package/dist/components/workflow-run-view/workflow-run-states.js.map +1 -1
- package/dist/components/workflow-run-view/workflow-run-view.d.ts +1 -3
- package/dist/components/workflow-run-view/workflow-run-view.d.ts.map +1 -1
- package/dist/components/workflow-run-view/workflow-run-view.js +217 -59
- package/dist/components/workflow-run-view/workflow-run-view.js.map +1 -1
- package/dist/core/entities/job-execution.d.ts +7 -0
- package/dist/core/entities/job-execution.d.ts.map +1 -1
- package/dist/core/entities/job-execution.js.map +1 -1
- package/dist/core/entities/job.d.ts +9 -0
- package/dist/core/entities/job.d.ts.map +1 -1
- package/dist/core/entities/job.js.map +1 -1
- package/dist/core/entities/step-attempt.d.ts +29 -0
- package/dist/core/entities/step-attempt.d.ts.map +1 -1
- package/dist/core/entities/step-attempt.js.map +1 -1
- package/dist/core/entities/step.d.ts +3 -1
- package/dist/core/entities/step.d.ts.map +1 -1
- package/dist/core/entities/step.js.map +1 -1
- package/dist/core/run-annotation.d.ts +79 -0
- package/dist/core/run-annotation.d.ts.map +1 -0
- package/dist/core/run-annotation.js +125 -0
- package/dist/core/run-annotation.js.map +1 -0
- package/dist/core/workflow-run.d.ts +1 -1
- package/dist/core/workflow-run.d.ts.map +1 -1
- package/dist/core/workflow-run.js.map +1 -1
- package/dist/hooks/api/annotations.d.ts +63 -0
- package/dist/hooks/api/annotations.d.ts.map +1 -0
- package/dist/hooks/api/annotations.js +145 -0
- package/dist/hooks/api/annotations.js.map +1 -0
- package/dist/hooks/api/run-annotation-mapper.d.ts +10 -0
- package/dist/hooks/api/run-annotation-mapper.d.ts.map +1 -0
- package/dist/hooks/api/run-annotation-mapper.js +22 -0
- package/dist/hooks/api/run-annotation-mapper.js.map +1 -0
- package/dist/hooks/api/run-annotations.d.ts +25 -0
- package/dist/hooks/api/run-annotations.d.ts.map +1 -0
- package/dist/hooks/api/run-annotations.js +78 -0
- package/dist/hooks/api/run-annotations.js.map +1 -0
- package/dist/hooks/api/step-attempt-detail.d.ts +14 -0
- package/dist/hooks/api/step-attempt-detail.d.ts.map +1 -0
- package/dist/hooks/api/step-attempt-detail.js +43 -0
- package/dist/hooks/api/step-attempt-detail.js.map +1 -0
- package/dist/hooks/api/workflow-run-mapper.d.ts +9 -2
- package/dist/hooks/api/workflow-run-mapper.d.ts.map +1 -1
- package/dist/hooks/api/workflow-run-mapper.js +47 -0
- package/dist/hooks/api/workflow-run-mapper.js.map +1 -1
- package/dist/pages/project-workflows-page.js +19 -19
- package/dist/pages/project-workflows-page.js.map +1 -1
- package/dist/pages/workflow-run-list-page.js +1 -1
- package/dist/pages/workflow-run-list-page.js.map +1 -1
- package/dist/routes/inputs.d.ts +7 -2
- package/dist/routes/inputs.d.ts.map +1 -1
- package/dist/routes/inputs.js +5 -6
- package/dist/routes/inputs.js.map +1 -1
- package/dist/tsconfig.test.tsbuildinfo +1 -1
- package/package.json +10 -9
- package/src/components/identifier/identifier.tsx +2 -2
- package/src/components/job-detail/agent-config-failure-callout.tsx +5 -1
- package/src/components/job-detail/job-context-panel.test.tsx +72 -0
- package/src/components/job-detail/job-context-panel.tsx +237 -0
- package/src/components/job-detail/job-detail-header.test.tsx +3 -0
- package/src/components/job-detail/job-detail-header.tsx +65 -34
- package/src/components/job-detail/job-detail-view.stories.tsx +555 -48
- package/src/components/job-detail/job-detail-view.tsx +101 -42
- package/src/components/job-detail/job-empty-states.tsx +23 -10
- package/src/components/job-detail/job-execution-switcher.tsx +5 -5
- package/src/components/job-detail/json-code.tsx +120 -0
- package/src/components/job-detail/step-attempt-log-panel.test.tsx +1 -0
- package/src/components/job-detail/step-attempt-log-panel.tsx +17 -6
- package/src/components/job-detail/step-troubleshooting.stories.tsx +120 -0
- package/src/components/job-detail/step-troubleshooting.test.tsx +337 -0
- package/src/components/job-detail/step-troubleshooting.tsx +537 -0
- package/src/components/job-graph/job-graph-content.tsx +4 -3
- package/src/components/job-graph/job-node.tsx +3 -3
- package/src/components/step-list/index.ts +1 -0
- package/src/components/step-list/step-list-model.ts +5 -0
- package/src/components/step-list/step-list.test.tsx +75 -2
- package/src/components/step-list/step-list.tsx +73 -20
- package/src/components/workflow-run-duration-label.tsx +1 -1
- package/src/components/workflow-run-list/job-status-strip.tsx +6 -6
- package/src/components/workflow-run-list/workflow-run-filter-menu.tsx +1 -1
- package/src/components/workflow-run-list/workflow-run-filters.tsx +4 -4
- package/src/components/workflow-run-list/workflow-run-list-states.tsx +6 -6
- package/src/components/workflow-run-list/workflow-run-list-view.tsx +1 -1
- package/src/components/workflow-run-list/workflow-run-row.tsx +7 -7
- package/src/components/workflow-run-summary/workflow-run-attempt-switcher.tsx +1 -1
- package/src/components/workflow-run-summary/workflow-run-summary.test.tsx +1 -1
- package/src/components/workflow-run-summary/workflow-run-summary.tsx +12 -12
- package/src/components/workflow-run-tabs/index.ts +7 -0
- package/src/components/workflow-run-tabs/run-annotation-count-chip.tsx +63 -0
- package/src/components/workflow-run-tabs/run-annotation-item.tsx +123 -0
- package/src/components/workflow-run-tabs/run-annotation-list.tsx +273 -0
- package/src/components/workflow-run-tabs/run-annotation-summary-line.test.tsx +77 -3
- package/src/components/workflow-run-tabs/run-annotation-summary-line.tsx +95 -20
- package/src/components/workflow-run-tabs/run-annotations.stories.tsx +293 -0
- package/src/components/workflow-run-tabs/severity-visuals.ts +37 -0
- package/src/components/workflow-run-view/run-workspace-nav.test.tsx +44 -0
- package/src/components/workflow-run-view/run-workspace-nav.tsx +22 -9
- package/src/components/workflow-run-view/workflow-run-states.tsx +6 -6
- package/src/components/workflow-run-view/workflow-run-view.test.tsx +246 -20
- package/src/components/workflow-run-view/workflow-run-view.tsx +255 -37
- package/src/core/entities/job-execution.ts +7 -0
- package/src/core/entities/job.ts +9 -0
- package/src/core/entities/step-attempt.ts +33 -0
- package/src/core/entities/step.ts +3 -1
- package/src/core/run-annotation.test.ts +315 -0
- package/src/core/run-annotation.ts +244 -0
- package/src/core/workflow-run.ts +4 -0
- package/src/hooks/api/annotations.test.ts +84 -0
- package/src/hooks/api/annotations.ts +240 -0
- package/src/hooks/api/run-annotation-mapper.ts +30 -0
- package/src/hooks/api/run-annotations.ts +137 -0
- package/src/hooks/api/step-attempt-detail.ts +67 -0
- package/src/hooks/api/workflow-run-mapper.ts +46 -0
- package/src/hooks/api/workflow-runs.test.tsx +61 -1
- package/src/pages/project-workflows-page.tsx +19 -19
- package/src/pages/workflow-job-detail-page.test.tsx +118 -1
- package/src/pages/workflow-run-list-page.tsx +1 -1
- package/src/routes/inputs.ts +7 -2
- package/test/fixtures/workflow-run.ts +7 -0
- package/tsconfig.build.tsbuildinfo +1 -1
- package/dist/core/workflow-run-tabs.d.ts +0 -9
- package/dist/core/workflow-run-tabs.d.ts.map +0 -1
- package/dist/core/workflow-run-tabs.js +0 -3
- package/dist/core/workflow-run-tabs.js.map +0 -1
- package/src/core/workflow-run-tabs.ts +0 -8
|
@@ -10,11 +10,18 @@ import {
|
|
|
10
10
|
SelectValue,
|
|
11
11
|
} from '@shipfox/react-ui/select';
|
|
12
12
|
import {toast} from '@shipfox/react-ui/toast';
|
|
13
|
+
import {Text} from '@shipfox/react-ui/typography';
|
|
13
14
|
import {useNavigate} from '@tanstack/react-router';
|
|
14
|
-
import {type ReactNode, useEffect} from 'react';
|
|
15
|
-
import
|
|
16
|
-
import
|
|
15
|
+
import {type ReactNode, useEffect, useMemo} from 'react';
|
|
16
|
+
import {buildRunAnnotationList, type RunAnnotationSummary} from '#core/run-annotation.js';
|
|
17
|
+
import {
|
|
18
|
+
type EvaluationTraceEntry,
|
|
19
|
+
isWorkflowRunTerminal,
|
|
20
|
+
type Job,
|
|
21
|
+
type WorkflowRunRerunMode,
|
|
22
|
+
} from '#core/workflow-run.js';
|
|
17
23
|
import {withoutWorkflowRunSelectionSearch} from '#core/workflow-run-url-state.js';
|
|
24
|
+
import {useRunAnnotationsQuery} from '#hooks/api/run-annotations.js';
|
|
18
25
|
import {
|
|
19
26
|
useCancelWorkflowRunMutation,
|
|
20
27
|
useRerunWorkflowRunMutation,
|
|
@@ -30,7 +37,11 @@ import {
|
|
|
30
37
|
import {JobGraph} from '../job-graph/index.js';
|
|
31
38
|
import type {JobGraphSelectionSource} from '../job-graph/types.js';
|
|
32
39
|
import {WorkflowRunSummary} from '../workflow-run-summary/index.js';
|
|
33
|
-
import {
|
|
40
|
+
import {
|
|
41
|
+
type DerivedRunAnnotation,
|
|
42
|
+
RunAnnotationList,
|
|
43
|
+
RunAnnotationSummaryLine,
|
|
44
|
+
} from '../workflow-run-tabs/index.js';
|
|
34
45
|
import {WorkflowSourceContent} from '../workflow-source-panel/index.js';
|
|
35
46
|
import {RunWorkspaceNav} from './run-workspace-nav.js';
|
|
36
47
|
import {resolveWorkflowRunSelection} from './workflow-run-selection.js';
|
|
@@ -51,7 +62,6 @@ export interface WorkflowRunViewProps {
|
|
|
51
62
|
runAttempt?: number | undefined;
|
|
52
63
|
selection?: WorkflowRunsSearch | undefined;
|
|
53
64
|
tab?: WorkflowRunTab | undefined;
|
|
54
|
-
annotationSummary?: RunAnnotationSummary | undefined;
|
|
55
65
|
activeJobId?: string | undefined;
|
|
56
66
|
jobSearch?: WorkflowJobSearch | undefined;
|
|
57
67
|
jobContent?: ReactNode | undefined;
|
|
@@ -69,7 +79,6 @@ export function WorkflowRunView({
|
|
|
69
79
|
runAttempt,
|
|
70
80
|
selection,
|
|
71
81
|
tab,
|
|
72
|
-
annotationSummary,
|
|
73
82
|
activeJobId,
|
|
74
83
|
jobSearch,
|
|
75
84
|
jobContent,
|
|
@@ -79,6 +88,22 @@ export function WorkflowRunView({
|
|
|
79
88
|
runAttempt: selection?.runAttempt ?? runAttempt,
|
|
80
89
|
});
|
|
81
90
|
const rerunMutation = useRerunWorkflowRunMutation(projectId);
|
|
91
|
+
// Annotations are read on their own cadence rather than hydrated into the run, so the two
|
|
92
|
+
// modules stay decoupled. The key is shared, so the job page's count chip costs no extra fetch.
|
|
93
|
+
//
|
|
94
|
+
// Polling is scoped to the surface that renders bodies. The read has no counts-only mode, so
|
|
95
|
+
// every poll transfers whole Markdown bodies; doing that every four seconds behind Summary,
|
|
96
|
+
// Source, and the job log spends megabytes to keep one rail number warm. Off that surface the
|
|
97
|
+
// counts still refresh on navigation and on window focus.
|
|
98
|
+
const annotationsQuery = useRunAnnotationsQuery({
|
|
99
|
+
workflowRunId,
|
|
100
|
+
runAttempt: runQuery.data?.runAttempt.attempt,
|
|
101
|
+
live:
|
|
102
|
+
runWorkspaceSection(tab) === 'annotations' &&
|
|
103
|
+
!activeJobId &&
|
|
104
|
+
Boolean(runQuery.data) &&
|
|
105
|
+
!isWorkflowRunTerminal(runQuery.data?.runAttempt.status ?? 'pending'),
|
|
106
|
+
});
|
|
82
107
|
|
|
83
108
|
return (
|
|
84
109
|
<RelativeTimeProvider>
|
|
@@ -87,11 +112,11 @@ export function WorkflowRunView({
|
|
|
87
112
|
workspaceSlug={workspaceSlug}
|
|
88
113
|
projectSlug={projectSlug}
|
|
89
114
|
query={runQuery}
|
|
115
|
+
annotations={annotationsQuery}
|
|
90
116
|
rerunMutation={rerunMutation}
|
|
91
117
|
runAttempt={runAttempt}
|
|
92
118
|
selection={selection}
|
|
93
119
|
tab={tab}
|
|
94
|
-
annotationSummary={annotationSummary}
|
|
95
120
|
activeJobId={activeJobId}
|
|
96
121
|
jobSearch={jobSearch}
|
|
97
122
|
jobContent={jobContent}
|
|
@@ -105,11 +130,11 @@ function RunViewContent({
|
|
|
105
130
|
workspaceSlug,
|
|
106
131
|
projectSlug,
|
|
107
132
|
query,
|
|
133
|
+
annotations,
|
|
108
134
|
rerunMutation,
|
|
109
135
|
runAttempt,
|
|
110
136
|
selection,
|
|
111
137
|
tab,
|
|
112
|
-
annotationSummary,
|
|
113
138
|
activeJobId,
|
|
114
139
|
jobSearch,
|
|
115
140
|
jobContent,
|
|
@@ -117,17 +142,18 @@ function RunViewContent({
|
|
|
117
142
|
workspaceSlug: string | undefined;
|
|
118
143
|
projectSlug: string | undefined;
|
|
119
144
|
query: ReturnType<typeof useWorkflowRunAttemptQuery>;
|
|
145
|
+
annotations: ReturnType<typeof useRunAnnotationsQuery>;
|
|
120
146
|
rerunMutation: ReturnType<typeof useRerunWorkflowRunMutation>;
|
|
121
147
|
runAttempt: number | undefined;
|
|
122
148
|
selection: WorkflowRunsSearch | undefined;
|
|
123
149
|
tab: WorkflowRunTab | undefined;
|
|
124
|
-
annotationSummary: RunAnnotationSummary | undefined;
|
|
125
150
|
activeJobId: string | undefined;
|
|
126
151
|
jobSearch: WorkflowJobSearch | undefined;
|
|
127
152
|
jobContent: ReactNode | undefined;
|
|
128
153
|
}) {
|
|
129
154
|
const navigate = useNavigate();
|
|
130
155
|
const runData = query.data;
|
|
156
|
+
const annotationSummary = annotations.summary;
|
|
131
157
|
const activeSection = runWorkspaceSection(tab);
|
|
132
158
|
const cancelMutation = useCancelWorkflowRunMutation(runData);
|
|
133
159
|
const sourceSnapshot = runData?.sourceSnapshot ?? null;
|
|
@@ -228,6 +254,24 @@ function RunViewContent({
|
|
|
228
254
|
});
|
|
229
255
|
}
|
|
230
256
|
|
|
257
|
+
function clearAnnotationFilters() {
|
|
258
|
+
if (!runData || !workspaceSlug || !projectSlug) return;
|
|
259
|
+
const nextSearch: WorkflowRunsSearch = {...selection, tab: 'annotations'};
|
|
260
|
+
delete nextSearch.jobId;
|
|
261
|
+
delete nextSearch.jobExecutionId;
|
|
262
|
+
delete nextSearch.stepId;
|
|
263
|
+
delete nextSearch.stepAttemptId;
|
|
264
|
+
delete nextSearch.severity;
|
|
265
|
+
delete nextSearch.annotation;
|
|
266
|
+
|
|
267
|
+
void navigate({
|
|
268
|
+
to: '/w/$workspaceSlug/p/$projectSlug/runs/$workflowRunId',
|
|
269
|
+
params: {workspaceSlug, projectSlug, workflowRunId: runData.id},
|
|
270
|
+
search: workflowRunSearchParams(nextSearch, nextSearch) as never,
|
|
271
|
+
replace: true,
|
|
272
|
+
});
|
|
273
|
+
}
|
|
274
|
+
|
|
231
275
|
function cancelRun() {
|
|
232
276
|
cancelMutation.mutate(undefined, {
|
|
233
277
|
onError: (error) => toast.error(cancelErrorMessage(error)),
|
|
@@ -291,6 +335,7 @@ function RunViewContent({
|
|
|
291
335
|
<RunSectionContent
|
|
292
336
|
section={activeSection}
|
|
293
337
|
run={runData}
|
|
338
|
+
annotations={annotations}
|
|
294
339
|
annotationSummary={annotationSummary}
|
|
295
340
|
workspaceSlug={workspaceSlug}
|
|
296
341
|
projectSlug={projectSlug}
|
|
@@ -298,11 +343,12 @@ function RunViewContent({
|
|
|
298
343
|
selectedJobId={selection?.jobId}
|
|
299
344
|
onSelectGraphJob={selectGraphJob}
|
|
300
345
|
onSelectAnnotationJob={selectAnnotationJob}
|
|
346
|
+
onClearAnnotationFilters={clearAnnotationFilters}
|
|
301
347
|
sourceSnapshot={sourceSnapshot}
|
|
302
348
|
highlightedLineRange={highlightedLineRange}
|
|
303
349
|
/>
|
|
304
350
|
) : (
|
|
305
|
-
<div className="min-h-0 flex-1 overflow-auto p-
|
|
351
|
+
<div className="min-h-0 flex-1 overflow-auto p-panel">{loadingOrError}</div>
|
|
306
352
|
)}
|
|
307
353
|
</div>
|
|
308
354
|
</div>
|
|
@@ -313,6 +359,7 @@ function RunViewContent({
|
|
|
313
359
|
function RunSectionContent({
|
|
314
360
|
section,
|
|
315
361
|
run,
|
|
362
|
+
annotations,
|
|
316
363
|
annotationSummary,
|
|
317
364
|
workspaceSlug,
|
|
318
365
|
projectSlug,
|
|
@@ -320,11 +367,13 @@ function RunSectionContent({
|
|
|
320
367
|
selectedJobId,
|
|
321
368
|
onSelectGraphJob,
|
|
322
369
|
onSelectAnnotationJob,
|
|
370
|
+
onClearAnnotationFilters,
|
|
323
371
|
sourceSnapshot,
|
|
324
372
|
highlightedLineRange,
|
|
325
373
|
}: {
|
|
326
374
|
section: RunWorkspaceSection;
|
|
327
375
|
run: NonNullable<ReturnType<typeof useWorkflowRunAttemptQuery>['data']>;
|
|
376
|
+
annotations: ReturnType<typeof useRunAnnotationsQuery>;
|
|
328
377
|
annotationSummary: RunAnnotationSummary | undefined;
|
|
329
378
|
workspaceSlug: string | undefined;
|
|
330
379
|
projectSlug: string | undefined;
|
|
@@ -332,6 +381,7 @@ function RunSectionContent({
|
|
|
332
381
|
selectedJobId: string | undefined;
|
|
333
382
|
onSelectGraphJob: (jobId: string | undefined, source?: JobGraphSelectionSource) => void;
|
|
334
383
|
onSelectAnnotationJob: (jobId: string | undefined) => void;
|
|
384
|
+
onClearAnnotationFilters: () => void;
|
|
335
385
|
sourceSnapshot: NonNullable<
|
|
336
386
|
ReturnType<typeof useWorkflowRunAttemptQuery>['data']
|
|
337
387
|
>['sourceSnapshot'];
|
|
@@ -341,8 +391,14 @@ function RunSectionContent({
|
|
|
341
391
|
}) {
|
|
342
392
|
if (section === 'summary') {
|
|
343
393
|
return (
|
|
344
|
-
<section
|
|
345
|
-
|
|
394
|
+
<section
|
|
395
|
+
aria-label="All jobs summary"
|
|
396
|
+
className="min-h-0 flex-1 overflow-auto pb-panel pt-[16px]"
|
|
397
|
+
>
|
|
398
|
+
<div className="mx-auto flex w-full max-w-[1120px] flex-col gap-group px-frame">
|
|
399
|
+
<Text as="h2" className="sr-only">
|
|
400
|
+
All jobs summary
|
|
401
|
+
</Text>
|
|
346
402
|
<JobGraph
|
|
347
403
|
run={run}
|
|
348
404
|
selectedJobId={selectedJobId}
|
|
@@ -355,33 +411,30 @@ function RunSectionContent({
|
|
|
355
411
|
}
|
|
356
412
|
|
|
357
413
|
if (section === 'annotations') {
|
|
358
|
-
const selectedJob = run.jobs.find((job) => job.id === selectedJobId);
|
|
359
414
|
return (
|
|
360
|
-
<
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
jobs={run.jobs}
|
|
372
|
-
selectedJobId={selectedJob?.id}
|
|
373
|
-
onSelect={onSelectAnnotationJob}
|
|
374
|
-
/>
|
|
375
|
-
</div>
|
|
376
|
-
<RunAnnotationsEmpty jobName={selectedJob?.displayName} />
|
|
377
|
-
</div>
|
|
378
|
-
</section>
|
|
415
|
+
<RunAnnotationsSection
|
|
416
|
+
run={run}
|
|
417
|
+
annotations={annotations}
|
|
418
|
+
annotationSummary={annotationSummary}
|
|
419
|
+
workspaceSlug={workspaceSlug}
|
|
420
|
+
projectSlug={projectSlug}
|
|
421
|
+
selection={selection}
|
|
422
|
+
selectedJobId={selectedJobId}
|
|
423
|
+
onSelectAnnotationJob={onSelectAnnotationJob}
|
|
424
|
+
onClearAnnotationFilters={onClearAnnotationFilters}
|
|
425
|
+
/>
|
|
379
426
|
);
|
|
380
427
|
}
|
|
381
428
|
|
|
382
429
|
return (
|
|
383
|
-
<section
|
|
384
|
-
|
|
430
|
+
<section
|
|
431
|
+
aria-label="Workflow source"
|
|
432
|
+
className="min-h-0 flex-1 overflow-auto pb-panel pt-[16px]"
|
|
433
|
+
>
|
|
434
|
+
<div className="mx-auto flex min-h-full w-full max-w-[1120px] flex-col px-frame">
|
|
435
|
+
<Text as="h2" className="sr-only">
|
|
436
|
+
Workflow source
|
|
437
|
+
</Text>
|
|
385
438
|
{sourceSnapshot ? (
|
|
386
439
|
<WorkflowSourceContent
|
|
387
440
|
source={sourceSnapshot}
|
|
@@ -405,6 +458,171 @@ function RunSectionContent({
|
|
|
405
458
|
);
|
|
406
459
|
}
|
|
407
460
|
|
|
461
|
+
function RunAnnotationsSection({
|
|
462
|
+
run,
|
|
463
|
+
annotations,
|
|
464
|
+
annotationSummary,
|
|
465
|
+
workspaceSlug,
|
|
466
|
+
projectSlug,
|
|
467
|
+
selection,
|
|
468
|
+
selectedJobId,
|
|
469
|
+
onSelectAnnotationJob,
|
|
470
|
+
onClearAnnotationFilters,
|
|
471
|
+
}: {
|
|
472
|
+
run: NonNullable<ReturnType<typeof useWorkflowRunAttemptQuery>['data']>;
|
|
473
|
+
annotations: ReturnType<typeof useRunAnnotationsQuery>;
|
|
474
|
+
annotationSummary: RunAnnotationSummary | undefined;
|
|
475
|
+
workspaceSlug: string | undefined;
|
|
476
|
+
projectSlug: string | undefined;
|
|
477
|
+
selection: WorkflowRunsSearch | undefined;
|
|
478
|
+
selectedJobId: string | undefined;
|
|
479
|
+
onSelectAnnotationJob: (jobId: string | undefined) => void;
|
|
480
|
+
onClearAnnotationFilters: () => void;
|
|
481
|
+
}) {
|
|
482
|
+
const selectedJob = run.jobs.find((job) => job.id === selectedJobId);
|
|
483
|
+
const severity = selection?.severity;
|
|
484
|
+
const records = annotations.annotations;
|
|
485
|
+
|
|
486
|
+
const entries = useMemo(
|
|
487
|
+
() =>
|
|
488
|
+
records
|
|
489
|
+
? buildRunAnnotationList({
|
|
490
|
+
annotations: records,
|
|
491
|
+
jobs: run.jobs,
|
|
492
|
+
severity,
|
|
493
|
+
jobId: selectedJob?.id,
|
|
494
|
+
})
|
|
495
|
+
: undefined,
|
|
496
|
+
[records, run.jobs, selectedJob?.id, severity],
|
|
497
|
+
);
|
|
498
|
+
const derivedAnnotations = useMemo<readonly DerivedRunAnnotation[] | undefined>(() => {
|
|
499
|
+
if (!records) return undefined;
|
|
500
|
+
const jobsWithAnnotations = new Set(records.map((annotation) => annotation.jobId));
|
|
501
|
+
|
|
502
|
+
return run.jobs
|
|
503
|
+
.filter((job) => {
|
|
504
|
+
const style = job.status === 'failed' ? 'error' : 'warning';
|
|
505
|
+
return (
|
|
506
|
+
(!selectedJob || selectedJob.id === job.id) &&
|
|
507
|
+
!jobsWithAnnotations.has(job.id) &&
|
|
508
|
+
(job.status === 'failed' || job.status === 'skipped') &&
|
|
509
|
+
job.jobExecutions.length === 0 &&
|
|
510
|
+
matchesDerivedAnnotationFilters(style, selection)
|
|
511
|
+
);
|
|
512
|
+
})
|
|
513
|
+
.map((job) => ({
|
|
514
|
+
id: `derived-${job.id}`,
|
|
515
|
+
style: job.status === 'failed' ? 'error' : 'warning',
|
|
516
|
+
body: derivedJobAnnotation(job),
|
|
517
|
+
}));
|
|
518
|
+
}, [records, run.jobs, selectedJob, selection]);
|
|
519
|
+
const hasSynthesizedJobAnnotations = run.jobs.some(
|
|
520
|
+
(job) =>
|
|
521
|
+
(job.status === 'failed' || job.status === 'skipped') && job.jobExecutions.length === 0,
|
|
522
|
+
);
|
|
523
|
+
|
|
524
|
+
return (
|
|
525
|
+
<section
|
|
526
|
+
aria-label="Run annotations"
|
|
527
|
+
className="min-h-0 flex-1 overflow-auto pb-panel pt-[16px]"
|
|
528
|
+
>
|
|
529
|
+
<div className="mx-auto flex w-full max-w-[1120px] flex-col gap-group px-frame">
|
|
530
|
+
<Text as="h2" className="sr-only">
|
|
531
|
+
Annotations
|
|
532
|
+
</Text>
|
|
533
|
+
<div className="flex flex-wrap items-center justify-between gap-inline">
|
|
534
|
+
<RunAnnotationSummaryLine
|
|
535
|
+
summary={annotationSummary}
|
|
536
|
+
workspaceSlug={workspaceSlug}
|
|
537
|
+
projectSlug={projectSlug}
|
|
538
|
+
workflowRunId={run.id}
|
|
539
|
+
search={selection}
|
|
540
|
+
/>
|
|
541
|
+
<AnnotationJobFilter
|
|
542
|
+
jobs={run.jobs}
|
|
543
|
+
selectedJobId={selectedJob?.id}
|
|
544
|
+
onSelect={onSelectAnnotationJob}
|
|
545
|
+
/>
|
|
546
|
+
</div>
|
|
547
|
+
<RunAnnotationList
|
|
548
|
+
// Remounting on a filter or run-attempt change resets the render window, so the next
|
|
549
|
+
// list never inherits a "show more" position from different data.
|
|
550
|
+
key={`${run.id}:${run.runAttempt.attempt}:${severity ?? 'all'}:${selectedJob?.id ?? 'all'}`}
|
|
551
|
+
query={annotations.query}
|
|
552
|
+
entries={entries}
|
|
553
|
+
derivedAnnotations={derivedAnnotations}
|
|
554
|
+
workspaceSlug={workspaceSlug}
|
|
555
|
+
projectSlug={projectSlug}
|
|
556
|
+
workflowRunId={run.id}
|
|
557
|
+
runAttempt={run.runAttempt.attempt}
|
|
558
|
+
// A run with no annotations at all offers no filter to clear, whatever the URL says.
|
|
559
|
+
filtered={Boolean(
|
|
560
|
+
(severity || selectedJob || selection?.annotation) &&
|
|
561
|
+
((annotationSummary?.total ?? 0) > 0 || hasSynthesizedJobAnnotations),
|
|
562
|
+
)}
|
|
563
|
+
filteredJobName={selectedJob?.displayName}
|
|
564
|
+
filteredSeverity={severity}
|
|
565
|
+
onClearFilters={onClearAnnotationFilters}
|
|
566
|
+
selectedAnnotationId={selection?.annotation}
|
|
567
|
+
/>
|
|
568
|
+
</div>
|
|
569
|
+
</section>
|
|
570
|
+
);
|
|
571
|
+
}
|
|
572
|
+
|
|
573
|
+
function matchesDerivedAnnotationFilters(
|
|
574
|
+
style: 'warning' | 'error',
|
|
575
|
+
selection: WorkflowRunsSearch | undefined,
|
|
576
|
+
): boolean {
|
|
577
|
+
if (selection?.severity && style !== selection.severity) return false;
|
|
578
|
+
// A selected annotation is a deep-link to a real annotation record. Synthetic diagnostics
|
|
579
|
+
// have no id or context, so they must not remain visible behind that selection.
|
|
580
|
+
return !selection?.annotation;
|
|
581
|
+
}
|
|
582
|
+
|
|
583
|
+
function derivedJobAnnotation(job: Job): string {
|
|
584
|
+
const reason = job.statusReason ? `Reason: \`${job.statusReason}\`` : null;
|
|
585
|
+
const traceSummary = formatConditionEvaluation(job.evaluationTrace);
|
|
586
|
+
const details = [reason, traceSummary].filter(Boolean).join('\n');
|
|
587
|
+
|
|
588
|
+
if (job.status === 'skipped') {
|
|
589
|
+
return [
|
|
590
|
+
`**${job.displayName}** was skipped before an execution was created.`,
|
|
591
|
+
'',
|
|
592
|
+
'Review its dependencies or condition before re-running.',
|
|
593
|
+
details,
|
|
594
|
+
]
|
|
595
|
+
.filter(Boolean)
|
|
596
|
+
.join('\n');
|
|
597
|
+
}
|
|
598
|
+
return [
|
|
599
|
+
`**${job.displayName}** failed before an execution was created.`,
|
|
600
|
+
'',
|
|
601
|
+
'Check runner availability and workflow configuration before re-running.',
|
|
602
|
+
details,
|
|
603
|
+
]
|
|
604
|
+
.filter(Boolean)
|
|
605
|
+
.join('\n');
|
|
606
|
+
}
|
|
607
|
+
|
|
608
|
+
function formatConditionEvaluation(
|
|
609
|
+
trace: readonly EvaluationTraceEntry[] | null | undefined,
|
|
610
|
+
): string | null {
|
|
611
|
+
if (!trace?.length) return null;
|
|
612
|
+
|
|
613
|
+
return [
|
|
614
|
+
'Condition evaluation:',
|
|
615
|
+
...trace.map((entry) => {
|
|
616
|
+
if ('dropped' in entry) {
|
|
617
|
+
return `- ${entry.dropped} additional evaluation${entry.dropped === 1 ? '' : 's'} not recorded`;
|
|
618
|
+
}
|
|
619
|
+
const value =
|
|
620
|
+
entry.value === undefined || entry.value === '' ? '(empty)' : `\`${entry.value}\``;
|
|
621
|
+
return `- \`${entry.field}\` evaluated \`${entry.expression}\` to ${value}${entry.degraded ? ' (degraded)' : ''}`;
|
|
622
|
+
}),
|
|
623
|
+
].join('\n');
|
|
624
|
+
}
|
|
625
|
+
|
|
408
626
|
const ALL_ANNOTATION_JOBS = 'all-jobs';
|
|
409
627
|
|
|
410
628
|
function AnnotationJobFilter({
|
|
@@ -448,11 +666,11 @@ function RunWorkspaceNavSkeleton() {
|
|
|
448
666
|
return (
|
|
449
667
|
<aside
|
|
450
668
|
aria-label="Loading run navigation"
|
|
451
|
-
className="hidden w-240 shrink-0 border-r border-border-neutral-base bg-background-neutral-background p-
|
|
669
|
+
className="hidden w-240 shrink-0 border-r border-border-neutral-base bg-background-neutral-background p-panel-compact min-[768px]:block"
|
|
452
670
|
>
|
|
453
|
-
<div className="flex flex-col gap-
|
|
671
|
+
<div className="flex flex-col gap-group">
|
|
454
672
|
<div className="h-32 rounded-4 bg-background-components-subtle" />
|
|
455
|
-
<div className="flex flex-col gap-
|
|
673
|
+
<div className="flex flex-col gap-inline">
|
|
456
674
|
<div className="h-16 w-64 rounded-4 bg-background-components-subtle" />
|
|
457
675
|
<div className="h-32 rounded-4 bg-background-components-subtle" />
|
|
458
676
|
<div className="h-32 rounded-4 bg-background-components-subtle" />
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import {type Duration, intervalToDuration} from 'date-fns';
|
|
2
2
|
import type {Step} from './step.js';
|
|
3
|
+
import type {EvaluationTraceEntry} from './step-attempt.js';
|
|
3
4
|
|
|
4
5
|
export type JobExecutionStatus = 'pending' | 'running' | 'succeeded' | 'failed' | 'cancelled';
|
|
5
6
|
export type JobExecutionDisplayStatus = JobExecutionStatus;
|
|
@@ -28,11 +29,14 @@ interface JobExecutionFields {
|
|
|
28
29
|
name: string;
|
|
29
30
|
status: JobExecutionStatus;
|
|
30
31
|
statusReason: string | null;
|
|
32
|
+
runner: string[] | null;
|
|
33
|
+
outputs: Record<string, unknown> | null;
|
|
31
34
|
triggerEvents: WorkflowExecutionEvent[];
|
|
32
35
|
queuedAt: string | null;
|
|
33
36
|
startedAt: string | null;
|
|
34
37
|
finishedAt: string | null;
|
|
35
38
|
timedOutAt: string | null;
|
|
39
|
+
evaluationTrace: EvaluationTraceEntry[] | null;
|
|
36
40
|
createdAt: string;
|
|
37
41
|
updatedAt: string;
|
|
38
42
|
steps: Step[];
|
|
@@ -45,11 +49,14 @@ export class JobExecution {
|
|
|
45
49
|
name!: string;
|
|
46
50
|
status!: JobExecutionStatus;
|
|
47
51
|
statusReason!: string | null;
|
|
52
|
+
runner!: string[] | null;
|
|
53
|
+
outputs!: Record<string, unknown> | null;
|
|
48
54
|
triggerEvents!: WorkflowExecutionEvent[];
|
|
49
55
|
queuedAt!: string | null;
|
|
50
56
|
startedAt!: string | null;
|
|
51
57
|
finishedAt!: string | null;
|
|
52
58
|
timedOutAt!: string | null;
|
|
59
|
+
evaluationTrace!: EvaluationTraceEntry[] | null;
|
|
53
60
|
createdAt!: string;
|
|
54
61
|
updatedAt!: string;
|
|
55
62
|
steps!: Step[];
|
package/src/core/entities/job.ts
CHANGED
|
@@ -3,6 +3,7 @@ import {
|
|
|
3
3
|
type JobExecution,
|
|
4
4
|
type JobExecutionDisplayDuration,
|
|
5
5
|
} from './job-execution.js';
|
|
6
|
+
import type {EvaluationTraceEntry} from './step-attempt.js';
|
|
6
7
|
|
|
7
8
|
export type JobStatus = 'pending' | 'running' | 'succeeded' | 'failed' | 'cancelled' | 'skipped';
|
|
8
9
|
export type JobDisplayStatus = JobStatus | 'listening';
|
|
@@ -75,6 +76,10 @@ interface JobFields {
|
|
|
75
76
|
status: JobStatus;
|
|
76
77
|
statusReason: JobStatusReason | null;
|
|
77
78
|
carriedOver: boolean;
|
|
79
|
+
outputs: Record<string, unknown> | null;
|
|
80
|
+
success: string | null;
|
|
81
|
+
runner: string[] | null;
|
|
82
|
+
evaluationTrace: EvaluationTraceEntry[] | null;
|
|
78
83
|
listening: JobListening | null;
|
|
79
84
|
listenerStatus: ListenerStatus;
|
|
80
85
|
resolutionReason: ResolutionReason | null;
|
|
@@ -94,6 +99,10 @@ export class Job {
|
|
|
94
99
|
status!: JobStatus;
|
|
95
100
|
statusReason!: JobStatusReason | null;
|
|
96
101
|
carriedOver!: boolean;
|
|
102
|
+
outputs!: Record<string, unknown> | null;
|
|
103
|
+
success!: string | null;
|
|
104
|
+
runner!: string[] | null;
|
|
105
|
+
evaluationTrace!: EvaluationTraceEntry[] | null;
|
|
97
106
|
listening!: JobListening | null;
|
|
98
107
|
listenerStatus!: ListenerStatus;
|
|
99
108
|
resolutionReason!: ResolutionReason | null;
|
|
@@ -13,6 +13,27 @@ export type StepAttemptDisplayDuration =
|
|
|
13
13
|
| {state: 'fixed'; elapsed: Duration}
|
|
14
14
|
| {state: 'live'; fromIso: string};
|
|
15
15
|
|
|
16
|
+
export interface EvaluationTraceValueEntry {
|
|
17
|
+
expression: string;
|
|
18
|
+
roots: string[];
|
|
19
|
+
fillTarget: string;
|
|
20
|
+
evaluatedAt: string;
|
|
21
|
+
field: string;
|
|
22
|
+
value?: string;
|
|
23
|
+
truncated?: boolean;
|
|
24
|
+
exprTruncated?: boolean;
|
|
25
|
+
reference?: boolean;
|
|
26
|
+
degraded?: boolean;
|
|
27
|
+
envKey?: string;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export interface EvaluationTraceLimitEntry {
|
|
31
|
+
truncated: true;
|
|
32
|
+
dropped: number;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export type EvaluationTraceEntry = EvaluationTraceValueEntry | EvaluationTraceLimitEntry;
|
|
36
|
+
|
|
16
37
|
interface StepAttemptFields {
|
|
17
38
|
id: string;
|
|
18
39
|
stepId: string;
|
|
@@ -22,6 +43,8 @@ interface StepAttemptFields {
|
|
|
22
43
|
status: string;
|
|
23
44
|
exitCode: number | null;
|
|
24
45
|
output: Record<string, unknown> | null;
|
|
46
|
+
outputs: Record<string, unknown> | null;
|
|
47
|
+
response: string | null;
|
|
25
48
|
error: Record<string, unknown> | null;
|
|
26
49
|
gateResult: StepGateResult;
|
|
27
50
|
restartFeedback: string | null;
|
|
@@ -38,6 +61,8 @@ export class StepAttempt {
|
|
|
38
61
|
status!: string;
|
|
39
62
|
exitCode!: number | null;
|
|
40
63
|
output!: Record<string, unknown> | null;
|
|
64
|
+
outputs!: Record<string, unknown> | null;
|
|
65
|
+
response!: string | null;
|
|
41
66
|
error!: Record<string, unknown> | null;
|
|
42
67
|
gateResult!: StepGateResult;
|
|
43
68
|
restartFeedback!: string | null;
|
|
@@ -53,6 +78,14 @@ export class StepAttempt {
|
|
|
53
78
|
}
|
|
54
79
|
}
|
|
55
80
|
|
|
81
|
+
export interface StepAttemptDetail {
|
|
82
|
+
stepId: string;
|
|
83
|
+
attempt: number;
|
|
84
|
+
authoredConfig: Record<string, unknown> | null;
|
|
85
|
+
config: Record<string, unknown> | null;
|
|
86
|
+
evaluationTrace: EvaluationTraceEntry[] | null;
|
|
87
|
+
}
|
|
88
|
+
|
|
56
89
|
export function stepAttemptDisplayDurationFromTimestamps({
|
|
57
90
|
startedAt,
|
|
58
91
|
finishedAt,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {StepAttempt} from './step-attempt.js';
|
|
1
|
+
import type {EvaluationTraceEntry, StepAttempt} from './step-attempt.js';
|
|
2
2
|
|
|
3
3
|
export type StepErrorReason =
|
|
4
4
|
| 'checkout_failed'
|
|
@@ -71,8 +71,10 @@ export interface Step {
|
|
|
71
71
|
name: string;
|
|
72
72
|
sourceLocation: StepSourceLocation | null;
|
|
73
73
|
status: string;
|
|
74
|
+
statusReason: string | null;
|
|
74
75
|
type: string;
|
|
75
76
|
config: Record<string, unknown>;
|
|
77
|
+
evaluationTrace: EvaluationTraceEntry[] | null;
|
|
76
78
|
agentConfig: AgentStepConfig | null;
|
|
77
79
|
error: StepError | null;
|
|
78
80
|
position: number;
|