1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
|
/**
* Turning results into the text the model reads.
*
* Twenty results with 600-character snippets is roughly 15KB, comfortably under
* pi's 50KB / 2000-line budget — but the truncation is applied anyway rather
* than argued about, because a pathological page could blow past it and an
* overflowing tool result costs the whole session, not just this call.
*/
import type { SearchResult } from "./extract.ts";
export type FormatInput = {
query: string;
searchUrl: string;
finalUrl: string;
endpoint: string;
/** Engine display name, e.g. "DuckDuckGo". */
engine: string;
/** Where the engine choice came from, e.g. "/search-engine". */
engineSource: string;
results: SearchResult[];
};
export const formatResults = (input: FormatInput): string => {
const lines: string[] = [
// Naming the engine on every result set matters more than it looks: the
// agent may have switched engines mid-conversation to get around a block,
// and results from different indexes are not interchangeable evidence.
`Search results for "${input.query}" — ${input.results.length} hits from ${input.engine} ` +
`(${input.engineSource}), via Chrome at ${input.endpoint}`,
`Query URL: ${input.searchUrl}`,
];
if (input.finalUrl !== input.searchUrl) lines.push(`Landed on: ${input.finalUrl}`);
lines.push("");
input.results.forEach((result, index) => {
lines.push(`${index + 1}. ${result.title}`);
lines.push(` ${result.url}`);
if (result.snippet) lines.push(` ${result.snippet}`);
lines.push("");
});
return lines.join("\n").trimEnd();
};
/**
* The note appended when pi's truncation utilities cut the output. Says what was
* lost and what to do about it — a bare "[truncated]" tells the model nothing it
* can act on, and there is no temp file to point at because the full text only
* ever existed in memory.
*/
export const truncationNote = (shown: number, total: number, bytesShown: string, bytesTotal: string): string =>
`\n\n[Output truncated: ${shown} of ${total} lines (${bytesShown} of ${bytesTotal}). ` +
`Re-run castle_cdp_search with a smaller numResults to see the rest.]`;
|