eve
Version:
Filesystem-first framework for durable backend AI agents that run anywhere.
197 lines • 9.87 kB
TypeScript
import type { Event } from '#compiled/@workflow/world/index.js';
/**
* Client-side latency measurement (TTFS / STSO / RSFS) threaded from the
* orchestrator's inline execution path into `executeStep`.
*
* TTFS (time-to-first-step) measures run creation → the first step's body
* beginning to execute. STSO (step-to-step overhead) measures the previous
* step's terminal event → the next step's body beginning to execute. RSFS
* (run-started-to-first-step) measures the `run_started` response landing →
* the first step's start POST being issued — a sub-window of TTFS that
* isolates replay overhead from the run-creation queue hop; `finalSchedulingReplay`
* is the synchronous workflow-function-execution duration of only the FINAL
* replay pass within that window (the pass that reached and scheduled the
* first step) — it is NOT accumulated across earlier pre-first-step passes
* (see {@link StepLatencyTracking.replayMs}), so it must not be read as "the
* replay portion of RSFS". All are attached to the step's terminal
* event so a backend can emit latency metrics from the event write alone,
* without extra event-log queries.
*
* Eligibility is decided by the orchestrator (which owns the event log) via
* {@link computeStepLatencyTracking}; the final values are computed by
* `executeStep` right before user code runs via
* {@link computeStepLatencyEventData}.
*/
export interface StepLatencyTracking {
/**
* Epoch ms of run creation (from the run-id ULID, falling back to the run
* snapshot's `createdAt`). Present only when the step qualifies for TTFS.
*/
ttfsAnchorMs?: number;
/**
* Wall-clock ms this invocation spent committing `hook_created` events
* before the first step (fire-and-forget `createHook()` ahead of the first
* step commits in the same suspension batch). Subtracted from TTFS so the
* metric reflects runtime overhead rather than the user's hook writes.
*/
preStepBlockingMs?: number;
/**
* Epoch ms the first pre-step `attr_set` write began (its client-stamped
* `occurredAt`, falling back to `createdAt`). When present, the TTFS
* measurement ENDS here instead of at the step's code start: a
* workflow-body `setAttributes` before the first step
* resolves through an extra replay (see the `hasAttributeEvents` branch in
* runtime.ts), so everything from this write until the step body runs is
* the duration of the setAttributes call — which is subtracted by ending
* the measurement at the point where the step would otherwise have been
* scheduled.
*/
preStepAttrStartMs?: number;
/**
* Epoch ms the previous step's terminal event was recorded (its
* client-stamped `occurredAt`, falling back to `createdAt`). Present only
* when the step qualifies for STSO.
*/
prevStepEndMs?: number;
/** Number of unique terminal steps already in the event log. */
stepCount?: number;
/** Number of events already in the event log. */
eventCount?: number;
/**
* Epoch ms the `run_started` response was received/parsed by the SDK.
* Present only when the step qualifies for RSFS — the same eligibility as
* TTFS (see {@link computeStepLatencyTracking}), plus a recoverable
* anchor. In turbo mode, `run_started` is backgrounded rather than
* awaited, so this is stamped at the point the runtime synthesizes the
* run locally and begins replay instead of at the real response; the
* first step's start POST is still chained on the real `run_started`
* promise (see step-executor.ts), so RSFS still ends up measuring the
* genuine run_started-to-first-step-POST stretch even though the two
* halves overlap under turbo.
*/
rsfsAnchorMs?: number;
/**
* Wall-clock ms this invocation's synchronous workflow-function replay
* took: from calling `runWorkflow` to it throwing the suspension that
* scheduled this batch. Excludes awaited network I/O (the suspension's
* event commits, the step's own start POST). Present only alongside
* `rsfsAnchorMs`.
*
* This is the FINAL replay pass only — the invocation that reached and
* scheduled the first step. Valid RSFS paths can replay more than once
* before the first step (e.g. a workflow-body `setAttributes()` detour
* replays twice), and a redelivery omits earlier invocations' replay work
* entirely; this value is not accumulated across those earlier passes.
* Do not read it as "the replay portion of RSFS" — RSFS
* ({@link rsfsAnchorMs}) covers the whole run_started-to-first-step
* window, this covers only the last pass.
*/
replayMs?: number;
/** Whether turbo mode is active for this invocation. */
turbo: boolean;
}
/** Latency telemetry attached to a step's terminal event's `eventData`. */
export interface StepLatencyEventData {
ttfs?: number;
stso?: number;
stepCount?: number;
eventCount?: number;
/** Client-measured run_started → first step's start POST, ms. */
rsfs?: number;
/**
* Client-measured wall-clock ms of the FINAL replay pass that scheduled
* the first step (see {@link StepLatencyTracking.replayMs}) — not
* accumulated across earlier pre-first-step passes, so it must not be
* read as "the replay portion of `rsfs`".
*/
finalSchedulingReplay?: number;
optimizations?: string[];
}
/**
* Decide, from the orchestrator's view of the event log, whether the inline
* step batch about to execute qualifies for TTFS and/or STSO measurement.
* Returns undefined when neither applies. Called once per batch; the result
* is passed to the batch's first step only, so a parallel first batch emits a
* single sample rather than one per sibling.
*/
export declare function computeStepLatencyTracking(params: {
/** The orchestrator's current in-memory event log (ascending order). */
events: Event[];
/**
* Whether this invocation's initial event load contained nothing beyond
* run_created/run_started/attr_set. Pre-existing hook events were written
* by an earlier invocation, so the time they added (including the queue
* hop back to this invocation) is unmeasurable and disqualifies TTFS.
* attr_set is permitted: a redelivery can land after a committed pre-step
* attr_set, and the detour it marks is subtracted via `preStepAttrStartMs`
* regardless of which invocation wrote it.
*/
invocationStartedClean: boolean;
/** Epoch ms of run creation, if recoverable. Absent disqualifies TTFS. */
runCreatedAtMs: number | undefined;
/**
* Epoch ms the `run_started` response was received/parsed by the SDK (or,
* under turbo, the instant the run was synthesized locally — see
* {@link StepLatencyTracking.rsfsAnchorMs}). Absent disqualifies RSFS.
*/
runStartedReceivedAtMs: number | undefined;
/**
* Wall-clock ms this suspension's `runWorkflow` call spent executing
* synchronously before throwing — the FINAL replay pass only, not
* accumulated across earlier passes. See
* {@link StepLatencyTracking.replayMs}.
*/
replayMs: number;
/** See {@link StepLatencyTracking.preStepBlockingMs}. */
preStepBlockingMs: number;
/**
* The accumulator's value as of the suspension that wrote the run's first
* attr_set (its hook phase runs before its attr writes). When the
* measurement ends at the attr write, only hook time from before that
* point may be subtracted — later hook writes fall outside the measured
* window. Undefined when no attr suspension happened in this invocation
* (e.g. the attr_set was loaded from a redelivery's snapshot, where no
* same-invocation hook time precedes it).
*/
preStepBlockingBeforeAttrMs: number | undefined;
/**
* Whether the suspension that scheduled this batch also created waits.
* Those `wait_created` writes are not in `events` yet (they were committed
* by this very suspension pass), so they must be reported separately. A
* wait disqualifies both measurements.
*/
suspensionHasWaits: boolean;
/**
* Whether the suspension that scheduled this batch also created hooks
* (also not in `events` yet). Hooks keep TTFS eligible — their measured
* write time is subtracted via `preStepBlockingMs` — but disqualify STSO,
* which is only meaningful for a pure back-to-back step gap.
*/
suspensionCreatedHooks: boolean;
/** Whether turbo mode is active for this invocation. */
turbo: boolean;
}): StepLatencyTracking | undefined;
/**
* Compute the latency telemetry to attach to the step's terminal event.
* Called by `executeStep` with the wall-clock timestamp taken immediately
* before user step code runs. Returns undefined when there is nothing to
* report (no tracking, or a retry attempt — retries measure neither TTFS nor
* STSO).
*/
export declare function computeStepLatencyEventData(params: {
tracking: StepLatencyTracking | undefined;
/** `Date.now()` taken immediately before user step code began executing. */
stepCodeStartedAtMs: number;
/**
* `Date.now()` taken immediately before the first step's start POST
* (`step_started`) was issued. Present only for the lazy inline steps RSFS
* cares about; see the call sites in step-executor.ts.
*/
stepStartPostSentAtMs: number | undefined;
attempt: number;
/** Whether this step was started lazily (no separate step_created write). */
lazyStepStart: boolean;
/** Whether the body ran optimistically, without awaiting step_started. */
optimisticStart: boolean;
}): StepLatencyEventData | undefined;
//# sourceMappingURL=step-latency.d.ts.map