History is kept by flow id: runs, cascades, rollups and events file the id in their flow column and nodes as <flow id>.<node>, the API answers flow plus flow_name and shows and takes nodes as <key>.<node>; events carry flow_id from the moment they are published; run queue items, the stage cache and cached curves keep ids and keys apart; endpoints, the brain graph, device bindings and search name the id to open

This commit is contained in:
2026-11-02 19:01:19 +01:00
parent e6027af8fe
commit d4a1b1db47
34 changed files with 1374 additions and 329 deletions
+54 -1
View File
@@ -453,6 +453,13 @@ export const BrainNodeSchema = {
type: 'array',
title: 'Flows'
},
flow_ids: {
items: {
type: 'string'
},
type: 'array',
title: 'Flow Ids'
},
issue: {
anyOf: [
{
@@ -970,7 +977,8 @@ export const DeadLetterSchema = {
},
type: 'object',
required: ['id', 'ts', 'flow', 'node', 'cause', 'reason'],
title: 'DeadLetter'
title: 'DeadLetter',
description: 'A work item given up on, named as the engine runs it: by key.'
} as const;
export const DeviceBindingSchema = {
@@ -979,6 +987,11 @@ export const DeviceBindingSchema = {
type: 'string',
title: 'Flow'
},
flow_id: {
type: 'string',
title: 'Flow Id',
default: ''
},
node: {
type: 'string',
title: 'Node'
@@ -1281,6 +1294,11 @@ export const EndpointSchema = {
type: 'string',
title: 'Id'
},
owner_id: {
type: 'string',
title: 'Owner Id',
default: ''
},
label: {
type: 'string',
title: 'Label'
@@ -1357,6 +1375,11 @@ export const EventRowSchema = {
type: 'string',
title: 'Flow'
},
flow_name: {
type: 'string',
title: 'Flow Name',
default: ''
},
node: {
type: 'string',
title: 'Node'
@@ -1891,6 +1914,11 @@ export const FlowRollupSchema = {
type: 'string',
title: 'Flow'
},
flow_name: {
type: 'string',
title: 'Flow Name',
default: ''
},
executions: {
type: 'integer',
title: 'Executions'
@@ -1941,6 +1969,11 @@ export const FlowRunsRowSchema = {
type: 'string',
title: 'Flow'
},
flow_name: {
type: 'string',
title: 'Flow Name',
default: ''
},
runs: {
type: 'integer',
title: 'Runs'
@@ -3985,6 +4018,11 @@ export const RunDetailSchema = {
type: 'string',
title: 'Flow'
},
flow_name: {
type: 'string',
title: 'Flow Name',
default: ''
},
status: {
type: 'string',
title: 'Status'
@@ -4243,6 +4281,11 @@ export const SearchEntrySchema = {
title: 'Parent',
default: ''
},
id: {
type: 'string',
title: 'Id',
default: ''
},
kind: {
type: 'string',
title: 'Kind',
@@ -5531,6 +5574,11 @@ export const fluksio__api__routes__observability__RunRowSchema = {
type: 'string',
title: 'Flow'
},
flow_name: {
type: 'string',
title: 'Flow Name',
default: ''
},
source: {
type: 'string',
title: 'Source'
@@ -5593,6 +5641,11 @@ export const fluksio__api__routes__runs__RunRowSchema = {
type: 'string',
title: 'Flow'
},
flow_name: {
type: 'string',
title: 'Flow Name',
default: ''
},
status: {
type: 'string',
title: 'Status'
+19 -11
View File
@@ -1902,6 +1902,9 @@ export class FlowsService {
/**
* Read Training
* A wren node's latest training run, or null when it has none.
*
* Found by the node it trains alone: only a training run names one, and
* the training flow may have been registered again under another id since.
* @param data The data for the request.
* @param data.flowId
* @param data.nodeId
@@ -2370,6 +2373,8 @@ export class ObservabilityService {
* the same pair ``/runs`` and ``/events`` take — so a chart dragged to a
* span can be re-fetched at that span's own resolution rather than
* magnifying the buckets it already has.
*
* ``flow`` is a flow id, ``node`` a ``<key>.<node>`` as the engine names it.
* @param data The data for the request.
* @param data.flow
* @param data.node
@@ -2449,6 +2454,7 @@ export class ObservabilityService {
*
* ``since`` is inclusive and ``until`` exclusive, so a window of one minute
* holds exactly the runs of the minute bucket the charts are drawn from.
* ``flow`` is a flow id.
* @param data The data for the request.
* @param data.flow
* @param data.status
@@ -2483,7 +2489,8 @@ export class ObservabilityService {
* takes, so a list can cover the span the charts beside it are drawn from.
* ``run`` narrows to one run — a batch run's id, or the journaled item a live
* cascade came from. Rows recorded before the column existed carry none, so
* an old failure answers no run at all rather than the wrong one.
* an old failure answers no run at all rather than the wrong one. ``flow``
* is a flow id.
* @param data The data for the request.
* @param data.kind
* @param data.flow
@@ -2577,7 +2584,7 @@ export class RunsService {
* Create Run
* Queue one run of a flow.
* @param data The data for the request.
* @param data.name
* @param data.flowId
* @param data.requestBody
* @returns fluksio__api__routes__runs__RunRow Successful Response
* @throws ApiError
@@ -2585,9 +2592,9 @@ export class RunsService {
public static createRun(data: RunsCreateRunData): CancelablePromise<RunsCreateRunResponse> {
return __request(OpenAPI, {
method: 'POST',
url: '/api/v1/runs/flows/{name}',
url: '/api/v1/runs/flows/{flow_id}',
path: {
name: data.name
flow_id: data.flowId
},
body: data.requestBody,
mediaType: 'application/json',
@@ -2605,7 +2612,7 @@ export class RunsService {
* search is this with the parameters spread out. Either way the caller
* builds the list — the engine does not own a sweep grammar.
* @param data The data for the request.
* @param data.name
* @param data.flowId
* @param data.requestBody
* @returns fluksio__api__routes__runs__RunRow Successful Response
* @throws ApiError
@@ -2613,9 +2620,9 @@ export class RunsService {
public static createSweep(data: RunsCreateSweepData): CancelablePromise<RunsCreateSweepResponse> {
return __request(OpenAPI, {
method: 'POST',
url: '/api/v1/runs/flows/{name}/sweep',
url: '/api/v1/runs/flows/{flow_id}/sweep',
path: {
name: data.name
flow_id: data.flowId
},
body: data.requestBody,
mediaType: 'application/json',
@@ -2658,7 +2665,7 @@ export class RunsService {
* first, so handing back the last row's ``created_at`` reads the next page
* whatever landed meanwhile — which ``offset`` cannot, since a run submitted
* between two pages shifts every row down one. ``since`` bounds the other
* end and is inclusive.
* end and is inclusive. ``flow`` is a flow id.
* @param data The data for the request.
* @param data.flow
* @param data.status
@@ -2693,7 +2700,7 @@ export class RunsService {
/**
* Delete Runs
* Every run of one flow at once.
* Every run of one flow at once, ``flow`` being its id.
*
* The counterpart to the list's ``flow`` filter, and what a reseed needs:
* deleting a flow leaves its runs standing on purpose, so this is the only
@@ -2915,8 +2922,9 @@ export class RunsService {
* Read Node Outputs
* What one node returned, by message, as the stage cache stored it.
*
* Kept only for a node that succeeded and may be reused, and only up to
* 256 kB of JSON. Null when the node published nothing.
* The node is ``<key>.<node>``, as the run shows it. Kept only for a node
* that succeeded and may be reused, and only up to 256 kB of JSON. Null when
* the node published nothing.
* @param data The data for the request.
* @param data.runId
* @param data.node
+15 -2
View File
@@ -112,6 +112,7 @@ export type BrainNode = {
kind: string;
members?: Array<(string)>;
flows?: Array<(string)>;
flow_ids?: Array<(string)>;
/**
* Why this neuron cannot run, if validation found something. A failure the engine hits while running arrives over the socket instead; this is the part that is already true before anything fires, and so has to travel with the graph.
*/
@@ -241,6 +242,9 @@ export type DashboardSummary = {
updated_at?: (string | null);
};
/**
* A work item given up on, named as the engine runs it: by key.
*/
export type DeadLetter = {
id: string;
ts: number;
@@ -255,6 +259,7 @@ export type DeadLetter = {
*/
export type DeviceBinding = {
flow: string;
flow_id?: string;
node: string;
port: string;
message: string;
@@ -380,6 +385,7 @@ export type DType = 'float' | 'int' | 'str' | 'bool' | 'json' | 'series' | 'reco
export type Endpoint = {
kind: string;
id: string;
owner_id?: string;
label: string;
detail?: string;
provides?: Array<(string)>;
@@ -396,6 +402,7 @@ export type EventRow = {
ts: string;
type: string;
flow: string;
flow_name?: string;
node: string;
detail: string;
actor: string;
@@ -569,6 +576,7 @@ export type FlowOrigin = {
export type FlowRollup = {
flow: string;
flow_name?: string;
executions: number;
errors: number;
messages: number;
@@ -583,6 +591,7 @@ export type FlowRollup = {
*/
export type FlowRunsRow = {
flow: string;
flow_name?: string;
runs: number;
running: number;
queued: number;
@@ -641,6 +650,7 @@ export type fluksio__api__routes__messages__PublishRequest = {
export type fluksio__api__routes__observability__RunRow = {
id: string;
flow: string;
flow_name?: string;
source: string;
parent?: string;
status: string;
@@ -658,6 +668,7 @@ export type fluksio__api__routes__observability__RunRow = {
export type fluksio__api__routes__runs__RunRow = {
id: string;
flow: string;
flow_name?: string;
status: string;
status_reason: string;
cause: string;
@@ -1305,6 +1316,7 @@ export type cause = 'api' | 'cli' | 'sdk';
export type RunDetail = {
id: string;
flow: string;
flow_name?: string;
status: string;
status_reason: string;
cause: string;
@@ -1373,6 +1385,7 @@ export type SearchEntry = {
name: string;
title?: string;
parent?: string;
id?: string;
kind?: string;
detail?: string;
};
@@ -2352,14 +2365,14 @@ export type PrivateCreateUserData = {
export type PrivateCreateUserResponse = (UserPublic);
export type RunsCreateRunData = {
name: string;
flowId: string;
requestBody: RunCreate;
};
export type RunsCreateRunResponse = (fluksio__api__routes__runs__RunRow);
export type RunsCreateSweepData = {
name: string;
flowId: string;
requestBody: SweepCreate;
};
+2 -2
View File
@@ -178,7 +178,7 @@ function RunForm({ flow }: { flow: string }) {
mutationFn: async () => {
if (grid.length > 1) {
return RunsService.createSweep({
name: flow,
flowId: flow,
requestBody: {
...flags,
runs: grid.map((params) => ({
@@ -190,7 +190,7 @@ function RunForm({ flow }: { flow: string }) {
})
}
return RunsService.createRun({
name: flow,
flowId: flow,
requestBody: {
...flags,
...withSeed,