import type { AgentSearch } from './agents.ts' // One search as the store is asked it: the agent's own hold, then what the model asked within it. // The agent's documents are its scope; a company the model names narrows the search to it. Pure, so the // merge is tested. /** What the model may ask of a search, beside its words. */ export interface Asked { ticker?: string /** One document by its id, like doc:notes.pdf. */ document?: string form?: string fiscal_year?: number fiscal_period?: string section?: string filed_after?: string filed_before?: string } export type Merged = { args: Record } | { refused: string } export function mergeSearch(query: string, pinned: AgentSearch, asked: Asked): Merged { const args: Record = { query } if (pinned.documents.length) args['scope_documents'] = pinned.documents if (pinned.origins.length) args['origins'] = pinned.origins const ticker = asked.ticker?.trim().toUpperCase() if (ticker) args['tickers'] = [ticker] const document = asked.document?.trim() if (document) args['documents'] = [document] const form = asked.form?.trim().toUpperCase() if (form) { if (pinned.forms.length && !pinned.forms.includes(form)) { return { refused: `${form} is not one of the forms you read: ${pinned.forms.join(', ')}.` } } args['forms'] = [form] } else if (pinned.forms.length) { args['forms'] = pinned.forms } if (typeof asked.fiscal_year === 'number' && Number.isInteger(asked.fiscal_year)) args['fiscal_years'] = [asked.fiscal_year] if (asked.fiscal_period?.trim()) args['fiscal_period'] = asked.fiscal_period.trim().toUpperCase() if (asked.section?.trim()) args['section'] = asked.section.trim() const after = [pinned.since, asked.filed_after?.trim()] .filter((d): d is string => Boolean(d)) .sort() .at(-1) if (after) args['filed_after'] = after if (asked.filed_before?.trim()) args['filed_before'] = asked.filed_before.trim() return { args } } /** What the model asked, read the forgiving way: a number given as text is a number. */ export function askedOf(input: Record): Asked { const text = (key: string): string | undefined => typeof input[key] === 'string' ? (input[key] as string) : undefined const year = typeof input['fiscal_year'] === 'number' ? input['fiscal_year'] : Number.parseInt(text('fiscal_year') ?? '', 10) return { ticker: text('ticker'), document: text('document'), form: text('form'), fiscal_year: Number.isFinite(year) ? (year as number) : undefined, fiscal_period: text('fiscal_period'), section: text('section'), filed_after: text('filed_after'), filed_before: text('filed_before'), } }