blob: 25852952dcb26816af09eb7daece8765a253eb25 [file]
// Copyright (C) 2026 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
import type {Engine} from '../../trace_processor/engine';
import type {SqlValue} from '../../trace_processor/query_result';
// A hard row cap on what a single query can return to the model. A stray
// `SELECT *` over a multi-million-row table would otherwise blow the context
// window; we truncate and tell the model the result is partial so it doesn't
// reason over it as complete (and is steered toward aggregation instead).
const MAX_ROWS = 100;
/**
* Run a PerfettoSQL query and serialise the result to a compact JSON string the
* model can read. Row-capped at MAX_ROWS (with a truncation note), and bigints
* are narrowed to numbers since JSON can't carry bigint.
*/
export async function runQueryForModel(
engine: Engine,
query: string,
): Promise<string> {
const result = await engine.query(query);
const columns = result.columns();
const rows: Array<Record<string, SqlValue | number>> = [];
let truncated = false;
for (const it = result.iter({}); it.valid(); it.next()) {
if (rows.length >= MAX_ROWS) {
truncated = true;
break;
}
const row: Record<string, SqlValue | number> = {};
for (const name of columns) {
const value = it.get(name);
row[name] = typeof value === 'bigint' ? Number(value) : value;
}
rows.push(row);
}
const payload = JSON.stringify({columns, rows});
if (truncated) {
return (
payload +
`\n... ${MAX_ROWS}+ rows; result truncated. Prefer COUNT/GROUP BY/` +
`LIMIT or aggregate rather than pulling raw rows.`
);
}
return payload;
}