feat: add multimodal search and granular performance diagnostics
Core CI / core (ubuntu-latest) (push) Failing after 3m31s
Core CI / core (macos-latest) (push) Canceled after 0s
Core CI / core (windows-latest) (push) Canceled after 0s
Core CI / desktop (ubuntu-latest) (push) Successful in 5m39s
Core CI / desktop (macos-latest) (push) Canceled after 0s
Core CI / desktop (windows-latest) (push) Canceled after 0s
Core CI / core (ubuntu-latest) (push) Failing after 3m31s
Core CI / core (macos-latest) (push) Canceled after 0s
Core CI / core (windows-latest) (push) Canceled after 0s
Core CI / desktop (ubuntu-latest) (push) Successful in 5m39s
Core CI / desktop (macos-latest) (push) Canceled after 0s
Core CI / desktop (windows-latest) (push) Canceled after 0s
This commit is contained in:
1 parent
d3bb8c7618
commit
b8400c4fbf
110 files changed
+79395
-250
No files matched your search
@@ -0,0 +1,203 @@
|
||||
/** UI times use performance.now(); native spans use their own command clock. */
|
||||
export interface NativeSpan {
|
||||
name: string;
|
||||
start_ms: number;
|
||||
duration_ms: number;
|
||||
parent: number | null;
|
||||
counters: Record<string, number>;
|
||||
}
|
||||
export interface NativeMetrics {
|
||||
total_ms: number;
|
||||
result_count: number;
|
||||
trace: NativeSpan[] | null;
|
||||
dropped_spans: number;
|
||||
}
|
||||
export interface MeasuredResponse<T> {
|
||||
results: T[];
|
||||
metrics: NativeMetrics;
|
||||
}
|
||||
export type SearchLane = "lexical" | "hybrid";
|
||||
export interface AttemptStart {
|
||||
lane: SearchLane;
|
||||
startedAt: number;
|
||||
submittedAt: number;
|
||||
submission: number;
|
||||
}
|
||||
interface Attempt {
|
||||
lane: SearchLane;
|
||||
submission: number;
|
||||
attempt: number;
|
||||
queued_ms: number;
|
||||
retry_wait_ms: number;
|
||||
invoke_ms: number;
|
||||
native: NativeMetrics | null;
|
||||
transport_estimate_ms: number | null;
|
||||
failed: boolean;
|
||||
ended_at: number;
|
||||
}
|
||||
|
||||
export class SearchMeasurement {
|
||||
debug: boolean;
|
||||
inputAt: number;
|
||||
scheduledAt: number;
|
||||
context: Record<string, string | number | boolean | null>;
|
||||
submissions = new Map<SearchLane, number>();
|
||||
latestSubmission = new Map<SearchLane, number>();
|
||||
submissionSequence = new Map<SearchLane, number>();
|
||||
laneAttempts = new Map<SearchLane, number>();
|
||||
attempts: Attempt[] = [];
|
||||
droppedAttempts = 0;
|
||||
droppedDisplays = 0;
|
||||
firstDisplayMs: number | null = null;
|
||||
displays: {
|
||||
lane: SearchLane;
|
||||
elapsed_ms: number;
|
||||
dom_update_ms: number;
|
||||
count: number;
|
||||
}[] = [];
|
||||
|
||||
constructor(
|
||||
inputAt: number,
|
||||
scheduledAt: number,
|
||||
debug: boolean,
|
||||
context: Record<string, string | number | boolean | null> = {},
|
||||
) {
|
||||
this.inputAt = inputAt;
|
||||
this.scheduledAt = scheduledAt;
|
||||
this.debug = debug;
|
||||
this.context = { ...context };
|
||||
}
|
||||
submitted(lane: SearchLane, at: number) {
|
||||
if (!this.submissions.has(lane)) this.submissions.set(lane, at);
|
||||
this.latestSubmission.set(lane, at);
|
||||
this.submissionSequence.set(
|
||||
lane,
|
||||
(this.submissionSequence.get(lane) ?? 0) + 1,
|
||||
);
|
||||
}
|
||||
begin(lane: SearchLane, startedAt: number): AttemptStart {
|
||||
return {
|
||||
lane,
|
||||
startedAt,
|
||||
submittedAt: this.latestSubmission.get(lane) ?? startedAt,
|
||||
submission: this.submissionSequence.get(lane) ?? 0,
|
||||
};
|
||||
}
|
||||
completed(
|
||||
token: AttemptStart,
|
||||
end: number,
|
||||
native: NativeMetrics | null,
|
||||
failed: boolean,
|
||||
) {
|
||||
const { lane, startedAt: start, submittedAt, submission } = token;
|
||||
const prior = this.attempts.filter((attempt) => attempt.lane === lane);
|
||||
const previous = prior.at(-1);
|
||||
const retry = previous?.failed && previous.submission === submission;
|
||||
const attemptNumber = (this.laneAttempts.get(lane) ?? 0) + 1;
|
||||
this.laneAttempts.set(lane, attemptNumber);
|
||||
const elapsed = Math.max(0, end - start);
|
||||
this.attempts.push({
|
||||
lane,
|
||||
submission,
|
||||
attempt: attemptNumber,
|
||||
queued_ms: retry ? 0 : Math.max(0, start - submittedAt),
|
||||
retry_wait_ms: retry ? Math.max(0, start - previous.ended_at) : 0,
|
||||
invoke_ms: elapsed,
|
||||
native,
|
||||
transport_estimate_ms: native
|
||||
? Math.max(0, elapsed - native.total_ms)
|
||||
: null,
|
||||
failed,
|
||||
ended_at: end,
|
||||
});
|
||||
if (this.attempts.length > (this.debug ? 32 : 4)) {
|
||||
this.attempts.shift();
|
||||
this.droppedAttempts++;
|
||||
}
|
||||
}
|
||||
displayed(lane: SearchLane, start: number, end: number, count: number) {
|
||||
if (this.firstDisplayMs === null)
|
||||
this.firstDisplayMs = Math.max(0, end - this.inputAt);
|
||||
this.displays.push({
|
||||
lane,
|
||||
elapsed_ms: Math.max(0, end - this.inputAt),
|
||||
dom_update_ms: Math.max(0, end - start),
|
||||
count,
|
||||
});
|
||||
if (this.displays.length > (this.debug ? 16 : 2)) {
|
||||
this.displays.shift();
|
||||
this.droppedDisplays++;
|
||||
}
|
||||
}
|
||||
latestNative(lane: SearchLane) {
|
||||
return (
|
||||
this.attempts
|
||||
.filter((attempt) => attempt.lane === lane && !attempt.failed)
|
||||
.at(-1)?.native ?? null
|
||||
);
|
||||
}
|
||||
/** Deliberately exclude query text, filenames, paths, snippets and errors. */
|
||||
export() {
|
||||
return {
|
||||
version: 1,
|
||||
context: this.context,
|
||||
clock_note:
|
||||
"UI monotonic elapsed times; native command-relative spans. Nested spans and parallel lanes must not be summed.",
|
||||
debounce_ms: Math.max(0, this.scheduledAt - this.inputAt),
|
||||
lane_schedule_ms: Object.fromEntries(
|
||||
[...this.submissions].map(([lane, at]) => [
|
||||
lane,
|
||||
Math.max(0, at - this.scheduledAt),
|
||||
]),
|
||||
),
|
||||
attempts: this.attempts.map(({ ended_at: _end, ...attempt }) => attempt),
|
||||
displays: this.displays,
|
||||
first_results_ms: this.firstDisplayMs,
|
||||
latest_displayed_ms: this.displays.at(-1)?.elapsed_ms ?? null,
|
||||
hybrid_final_results_ms:
|
||||
[...this.displays]
|
||||
.reverse()
|
||||
.find((display) => display.lane === "hybrid")?.elapsed_ms ?? null,
|
||||
dropped_attempts: this.droppedAttempts,
|
||||
dropped_displays: this.droppedDisplays,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export function measuredFailure(
|
||||
error: unknown,
|
||||
): { message: string; metrics: NativeMetrics } | null {
|
||||
if (!error || typeof error !== "object") return null;
|
||||
const value = error as { message?: unknown; metrics?: NativeMetrics };
|
||||
return typeof value.message === "string" &&
|
||||
value.metrics &&
|
||||
Number.isFinite(value.metrics.total_ms)
|
||||
? { message: value.message, metrics: value.metrics }
|
||||
: null;
|
||||
}
|
||||
|
||||
/** Malformed/cyclic parent chains cannot trap the debug renderer. */
|
||||
export function spanDepth(spans: NativeSpan[], index: number) {
|
||||
let depth = 0;
|
||||
const visited = new Set([index]);
|
||||
let parent = spans[index]?.parent;
|
||||
while (
|
||||
parent != null &&
|
||||
spans[parent] &&
|
||||
!visited.has(parent) &&
|
||||
depth < 16
|
||||
) {
|
||||
visited.add(parent);
|
||||
depth++;
|
||||
parent = spans[parent].parent;
|
||||
}
|
||||
return depth;
|
||||
}
|
||||
|
||||
export function briefMs(value: number) {
|
||||
return value < 1
|
||||
? "<1"
|
||||
: value < 10
|
||||
? value.toFixed(1)
|
||||
: String(Math.round(value));
|
||||
}
|
||||
Reference in new issue
Block a user