You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
fix(v2): honour a requested stats window, and answer a claimed graph id with a conflict
Log statistics accepted a start and an end, filtered the totals by them, and
then built the series against wall-clock now. Bucket width was computed over a
span the caller never asked for, and every bucket past the requested end was
structurally empty - so a bounded historical query returned a wrong-width series
with fabricated trailing buckets, under a window label that disagreed with the
request. Each edge now honours the bound it was given and keeps its previous
derivation when omitted, so an unbounded request is unchanged.
Separately, block, edge and subflow ids are global primary keys while the
delete that precedes a state replace is scoped to one workflow. An id owned by
another workflow survived that delete, the insert violated the key, and because
callers pass their own transaction the driver error escaped unclassified as a
server fault. The write now refuses such an id up front with a conflict naming
it, and re-classifies the same violation if one races past the check, since the
lock covers only the workflow being written. The dry run checks the ids a commit
would insert and reports the warnings a commit would report, which is what its
own contract already promised.
Copy file name to clipboardExpand all lines: apps/sim/lib/api/contracts/v2/logs-stats.ts
+1-1Lines changed: 1 addition & 1 deletion
Original file line number
Diff line number
Diff line change
@@ -105,7 +105,7 @@ export const v2LogStatsSchema = z
105
105
end: v2TimestampSchema.describe('ISO 8601 end of the window.'),
106
106
})
107
107
.describe(
108
-
'The window the buckets span: the oldest matching run through the later of the newest matching run and now. A workspace with no matching runs reports the trailing 24 hours.'
108
+
'The window the buckets span. `startDate` and `endDate` are used verbatim when supplied; an omitted edge falls back to the oldest matching run on the left and to the later of the newest matching run and now on the right. With no matching runs the window is 24 hours wide, measured back from that right edge — the trailing 24 hours when no `endDate` was supplied, and the 24 hours preceding `endDate` when one was supplied without a `startDate`.'
109
109
),
110
110
segmentMs: z.number().describe('Width of one bucket in milliseconds.'),
Copy file name to clipboardExpand all lines: apps/sim/lib/api/contracts/v2/openapi/logs.ts
+1-1Lines changed: 1 addition & 1 deletion
Original file line number
Diff line number
Diff line change
@@ -207,7 +207,7 @@ const declaredRoutes = [
207
207
logsOperation({
208
208
operationId: 'getLogStats',
209
209
summary: 'Get Log Statistics',
210
-
description: `Bucketed run counts, success rate, error count, and mean latency for a workspace and for each of its workflows — the aggregate a caller would otherwise have to page every run to compute. The window spans the oldest matching run through the later of the newest matching run and now, divided into exactly \`segmentCount\` equal buckets whose width is \`max(60000, floor(windowMs / segmentCount))\` milliseconds. The one-minute floor is a floor on bucket width, not on the window: when it applies, the series runs past \`timeBounds.end\` and the trailing buckets are empty rather than the window being compressed. A folder path covers its whole subtree. Per-workflow series are capped and \`workflowsTruncated\` reports whether the cap applied; the workspace totals are always computed from every workflow. ${RUN_RETENTION}${FOLDER_TREE_TOO_LARGE}`,
210
+
description: `Bucketed run counts, success rate, error count, and mean latency for a workspace and for each of its workflows — the aggregate a caller would otherwise have to page every run to compute. The window spans \`startDate\` through \`endDate\` when both are supplied; an omitted edge falls back to the oldest matching run on the left and to the later of the newest matching run and now on the right. With no matching runs the window is 24 hours wide, measured back from that right edge — the trailing 24 hours when no \`endDate\` was supplied, and the 24 hours preceding \`endDate\` when one was supplied without a \`startDate\`. The window is divided into exactly \`segmentCount\` equal buckets whose width is \`max(60000, floor(windowMs / segmentCount))\` milliseconds. The one-minute floor is a floor on bucket width, not on the window: when it applies, the series runs past \`timeBounds.end\` and the trailing buckets are empty rather than the window being compressed. A folder path covers its whole subtree. Per-workflow series are capped and \`workflowsTruncated\` reports whether the cap applied; the workspace totals are always computed from every workflow. ${RUN_RETENTION}${FOLDER_TREE_TOO_LARGE}`,
211
211
errors: [...RESOURCE_ERRORS,'PayloadTooLarge'],
212
212
success: {description: 'Bucketed execution statistics for the workspace.'},
0 commit comments