fix(tool-web): unexport renderFetchOutput so its memo stays behind the frozen path
renderFetchOutput has no external consumer: only formatFetchOutput and fetchMetaFromValue call it, both through the registry, which deep-freezes the result value. Exporting it let a hypothetical caller mutate a cached input or the returned RenderedFetch and desync the card's truncated flag from the model text. Drop it from the barrel and document that the memo needs no defensive copy because every caller is internal and read-only.
This commit is contained in:
@@ -266,10 +266,14 @@ interface RenderedFetch {
|
||||
* limits the source prefix processed synchronously, then applies again where the
|
||||
* complete output — header, rendered body, and footer — is known.
|
||||
*
|
||||
* The tool registry calls this once through `output.render` and again through
|
||||
* `output.presentationMeta`, both with the same frozen result value; the
|
||||
* conversion is memoized per `(result, maxOutputChars)` so the synchronous DOM
|
||||
* parse and turndown walk run once, not twice, on the same body.
|
||||
* Package-internal: the only callers are {@link formatFetchOutput} and
|
||||
* {@link fetchMetaFromValue}, both reached through the tool registry, which
|
||||
* deep-freezes the result value before calling `output.render` and
|
||||
* `output.presentationMeta`. The conversion is memoized per
|
||||
* `(result, maxOutputChars)` so the synchronous DOM parse and turndown walk run
|
||||
* once, not twice, on that same frozen value. Keeping it unexported means no
|
||||
* caller can mutate a cached input or the returned {@link RenderedFetch}, so the
|
||||
* memo needs no defensive copy.
|
||||
*
|
||||
* @param result - the seam's fetch outcome.
|
||||
* @param maxOutputChars - cap on the complete returned string; a cut body gets
|
||||
@@ -277,7 +281,7 @@ interface RenderedFetch {
|
||||
* @returns the complete `Fetched <url> (HTTP <status>)`-headed text and whether
|
||||
* the provider, a source cut, or the cap trimmed the content.
|
||||
*/
|
||||
export function renderFetchOutput(result: WebFetchResult, maxOutputChars: number): RenderedFetch {
|
||||
function renderFetchOutput(result: WebFetchResult, maxOutputChars: number): RenderedFetch {
|
||||
const byCap = renderCache.get(result) ?? new Map<number, RenderedFetch>()
|
||||
const cached = byCap.get(maxOutputChars)
|
||||
if (cached !== undefined) return cached
|
||||
|
||||
@@ -14,7 +14,7 @@ import { applyWebFetchTool } from './fetch.ts'
|
||||
|
||||
export { WEB_SEARCH_MAX_RESULTS, applyWebSearchTool, formatSearchOutput, parseSearchArgs, presentSearchCall, presentSearchResult, searchMetaFromValue, searchMetaFromResult } from './search.ts'
|
||||
export type { WebSearchMeta } from './search.ts'
|
||||
export { applyWebFetchTool, formatFetchOutput, renderFetchOutput, parseFetchArgs, presentFetchCall, presentFetchResult, fetchMetaFromValue, fetchMetaFromResult } from './fetch.ts'
|
||||
export { applyWebFetchTool, formatFetchOutput, parseFetchArgs, presentFetchCall, presentFetchResult, fetchMetaFromValue, fetchMetaFromResult } from './fetch.ts'
|
||||
export type { WebFetchMeta } from './fetch.ts'
|
||||
|
||||
/** Cordis plugin name used by loader diagnostics. */
|
||||
|
||||
Reference in New Issue
Block a user