/** * The lookup layer: search, read-by-id, renewals and provider inventory. * * Two things are covered here and nothing else. The first is the contract with * the model — every name inside the PIG boundary, every input schema strict and * bounded — because those are the failures that reach a user as a tool call * that never runs. The second is the shaping, which is pure by design so that * this suite can reach it: the unit suite runs in CI BEFORE the migration step, * against a database with no tables, so anything needing a row belongs in * `e2e/`. * * Shaping is where the expensive mistakes live. A count taken off a capped list * is asserted to the user as a total; an exact name match sorted below a * coincidental substring sends the model to the wrong account; a lapsed renewal * notice sorted below a distant expiry hides the only row anyone was looking * for. All three typecheck. */ import assert from 'node:assert/strict'; import test from 'node:test'; import type { Database } from '@pig/db'; import { zodToJsonSchema } from 'zod-to-json-schema'; import { assertPigToolBoundary } from '../src/chat'; import type { ResultScope } from '../src/page-tools'; import { assembleInventoryResult, assembleRenewals, assembleSearchResult, createLookupPigTools, likeFragment, type InventoryOffer, type RenewalContract, type SearchRowSets, } from '../src/chat-tools'; /** Schema and naming checks run before any query, so identity is enough. */ const db = {} as Database; const tools = createLookupPigTools(db); function tool(name: string) { const found = tools.find((candidate) => candidate.name === name); assert.ok(found, `${name} is registered`); return found; } function accepts(name: string, input: unknown): boolean { return tool(name).inputSchema.safeParse(input).success; } // --------------------------------------------------------------------------- // The boundary // --------------------------------------------------------------------------- test('every lookup tool sits inside the PIG tool boundary', () => { assert.deepEqual(tools.map((entry) => entry.name), [ 'pig_search_records', 'pig_get_record_by_id', 'pig_list_renewals', 'pig_list_inventory', ]); // The assertion the chat provider runs on every request. A name that fails it // takes the whole conversation down rather than one tool. assert.doesNotThrow(() => assertPigToolBoundary(tools)); for (const entry of tools) { assert.ok(entry.name.startsWith('pig_'), entry.name); // Nothing here may read as a shell, filesystem or code-execution tool: the // system prompt tells the model it has none, and a name that suggests // otherwise is an invitation to try. assert.doesNotMatch(entry.name, /bash|shell|filesystem|file_read|file_write|exec|eval/i); assert.ok(entry.description.length > 40, `${entry.name} has a usable description`); } }); // --------------------------------------------------------------------------- // The input bounds // --------------------------------------------------------------------------- test('the search query is bounded at both ends because it comes from a model', () => { assert.equal(accepts('pig_search_records', { query: 'Halcyon' }), true); // Trimmed before the length check, so trailing whitespace cannot smuggle a // one-character query past the floor. assert.equal(accepts('pig_search_records', { query: ' H ' }), false); assert.equal(accepts('pig_search_records', { query: '' }), false); assert.equal(accepts('pig_search_records', { query: 'a' }), false); assert.equal(accepts('pig_search_records', { query: 'x'.repeat(64) }), true); assert.equal(accepts('pig_search_records', { query: 'x'.repeat(65) }), false); // A model that pastes an entire user turn into the query would otherwise put // arbitrary text into a LIKE pattern and get the whole book back. assert.equal(accepts('pig_search_records', { query: 'x'.repeat(4000) }), false); assert.equal(accepts('pig_search_records', {}), false); assert.equal(accepts('pig_search_records', { query: 'Halcyon', limit: 500 }), false); }); test('LIKE wildcards in a model-supplied query are escaped, not honoured', () => { // `%` unescaped matches every row in every searched table, and the model is // handed the first five of each as though they answered the question. assert.equal(likeFragment('%'), '%\\%%'); assert.equal(likeFragment('_'), '%\\_%'); assert.equal(likeFragment('a\\b'), '%a\\\\b%'); assert.equal(likeFragment('Halcyon'), '%Halcyon%'); }); test('read-by-id takes a known record type and a real uuid', () => { const id = '20000000-0000-4000-8000-000000000002'; assert.equal(accepts('pig_get_record_by_id', { type: 'account', id }), true); assert.equal(accepts('pig_get_record_by_id', { type: 'commitment', id }), true); // An id the model invented is far more likely than one it mistyped, and a // free-text id would reach the database as a cast error rather than a miss. assert.equal(accepts('pig_get_record_by_id', { type: 'account', id: 'halcyon' }), false); assert.equal(accepts('pig_get_record_by_id', { type: 'invoice', id }), false); assert.equal(accepts('pig_get_record_by_id', { id }), false); assert.equal(accepts('pig_get_record_by_id', { type: 'account', id, expand: true }), false); }); test('the renewal and inventory filters reject everything they do not name', () => { assert.equal(accepts('pig_list_renewals', {}), true); assert.equal(accepts('pig_list_renewals', { side: 'demand' }), true); assert.equal(accepts('pig_list_renewals', { side: 'supply' }), true); assert.equal(accepts('pig_list_renewals', { side: 'both' }), false); assert.equal(accepts('pig_list_renewals', { withinDays: 30 }), false); assert.equal(accepts('pig_list_inventory', {}), true); assert.equal(accepts('pig_list_inventory', { gpuType: 'H100' }), true); assert.equal(accepts('pig_list_inventory', { gpuType: 'x'.repeat(25) }), false); assert.equal(accepts('pig_list_inventory', { minGpuCount: 8 }), true); assert.equal(accepts('pig_list_inventory', { minGpuCount: 0 }), false); assert.equal(accepts('pig_list_inventory', { minGpuCount: 8.5 }), false); assert.equal(accepts('pig_list_inventory', { minGpuCount: 1_000_000 }), false); assert.equal(accepts('pig_list_inventory', { requiresFastInterconnect: true }), true); assert.equal(accepts('pig_list_inventory', { maxPriceCents: 200 }), false); }); /** * What the model is actually sent, rather than what the zod reads like. * * `zodToJsonSchema(..., { target: 'openAi' })` — the exact call both inference * paths make — emits an optional field as REQUIRED and nullable. Two failures * follow from that and neither is visible in TypeScript: a schema-abiding model * sends `null` and `.optional()` rejects it, and a `.describe()` applied after * the wrapper is dropped from the emitted schema, so the sentence explaining * the parameter never reaches the prompt. */ function emittedSchema(name: string): { properties?: Record; required?: string[]; } { return zodToJsonSchema(tool(name).inputSchema, { $refStrategy: 'none', target: 'openAi' }) as { properties?: Record; required?: string[]; }; } test('an optional parameter accepts the null the emitted schema asks for', () => { assert.equal(accepts('pig_list_renewals', { side: null }), true); assert.equal( accepts('pig_list_inventory', { gpuType: null, minGpuCount: null, requiresFastInterconnect: null, }), true, ); // The schema tells the model these are required, so a model that obeys it // sends all three every time — including when it wants no filter at all. assert.deepEqual(emittedSchema('pig_list_inventory').required, [ 'gpuType', 'minGpuCount', 'requiresFastInterconnect', ]); }); test('every parameter description survives into the emitted schema', () => { for (const entry of tools) { const properties = emittedSchema(entry.name).properties ?? {}; for (const [parameter, shape] of Object.entries(properties)) { assert.ok( shape.description && shape.description.length > 10, `${entry.name}.${parameter} reaches the model with no description`, ); } } }); // --------------------------------------------------------------------------- // Search shaping // --------------------------------------------------------------------------- /** * The five denominators, roughly the demo book's own shape. * * A search reports how many rows it matched; without these it would be the only * count in its own payload, and "3 accounts match" is one careless sentence away * from "we have 3 accounts". */ const TOTALS = { account: 23, demand_deal: 13, supply_deal: 8, contract: 20, commitment: 6, } as const; /** Every row in every searched table: the denominator the headline quotes. */ const SEARCHABLE = Object.values(TOTALS).reduce((sum, rows) => sum + rows, 0); const emptySets: SearchRowSets = { accounts: [], demandDeals: [], supplyDeals: [], contracts: [], commitments: [], accountNames: new Map(), totals: { ...TOTALS }, }; function account(name: string, id = name): SearchRowSets['accounts'][number] { return { id, name, side: 'demand', customerSegment: 'enterprise', country: 'US' }; } interface SearchReading { headline: string; truncated: boolean; counts: Record; totals: Record; scope: ResultScope; results: { type: string; id: string; name: string }[]; } test('an exact name outranks a prefix, and a prefix outranks a substring', () => { const reading = assembleSearchResult('meridian', { ...emptySets, accounts: [ account('Old Meridian Holdings'), account('Meridian Sovereign Cloud'), account('Meridian'), ], }) as SearchReading; assert.deepEqual(reading.results.map((row) => row.name), [ 'Meridian', 'Meridian Sovereign Cloud', 'Old Meridian Holdings', ]); }); test('at equal match quality the account comes first, because it reaches the rest', () => { const reading = assembleSearchResult('halcyon', { ...emptySets, accounts: [account('DEMO — Halcyon Research', 'acct')], contracts: [ { id: 'dpa', title: 'DEMO — DPA — Halcyon Research', accountId: 'acct', contractType: 'dpa', status: 'executed', side: 'demand', expiresAt: null, valueCents: null, }, ], accountNames: new Map([['acct', 'DEMO — Halcyon Research']]), }) as SearchReading; // Alphabetically the addendum wins, and that is the wrong answer to // "tell me about Halcyon". assert.deepEqual(reading.results.map((row) => row.type), ['account', 'contract']); }); test('a search result is capped per type and overall, and says when it was cut', () => { const six = Array.from({ length: 6 }, (_, i) => account(`Alpha ${i}`, `a${i}`)); const reading = assembleSearchResult('alpha', { ...emptySets, accounts: six }) as SearchReading; // Six rows come back from a five-row budget precisely so the cut is visible; // the sixth is evidence, never a result. assert.equal(reading.results.length, 5); assert.equal(reading.counts.account, 5); assert.equal(reading.truncated, true); // The model quotes the headline, so the hedge has to live in it rather than // in a `truncated` flag further down the payload. assert.match(reading.headline, new RegExp(`At least 5 of ${SEARCHABLE} searchable record\\(s\\)`)); // The denominator travels with the hedge: a capped match count next to the // number of rows it was drawn from cannot be read as "we have five accounts". assert.equal(reading.scope.matched, 5); assert.equal(reading.scope.total, SEARCHABLE); assert.equal(reading.totals.account, TOTALS.account); }); test('the overall cap holds even when no single type reached its own', () => { const three = (prefix: string) => Array.from({ length: 3 }, (_, i) => `${prefix} ${i}`); const reading = assembleSearchResult('block', { totals: { ...TOTALS }, accounts: three('block acct').map((name) => account(name, name)), demandDeals: three('block demand').map((name) => ({ id: name, name, accountId: 'acct', stage: 'proposal', acvCents: 1_000_000, tcvCents: 2_500_000, expectedCloseDate: new Date('2026-09-01T00:00:00.000Z'), })), supplyDeals: three('block supply').map((name) => ({ id: name, name, accountId: 'acct', stage: 'sourced', gpuType: 'H100_80GB', gpuCount: 64, targetCostPerGpuHourCents: 189, })), contracts: three('block msa').map((name) => ({ id: name, title: name, accountId: 'acct', contractType: 'msa', status: 'executed', side: 'demand', expiresAt: new Date('2027-01-01T00:00:00.000Z'), valueCents: 125_722_500, })), commitments: three('block cap').map((name) => ({ id: name, name, accountId: 'acct', gpuType: 'H200', gpuCount: 128, startsAt: new Date('2026-01-01T00:00:00.000Z'), endsAt: new Date('2027-01-01T00:00:00.000Z'), costPerGpuHourCents: 210, })), accountNames: new Map([['acct', 'DEMO — Halcyon Research']]), }) as SearchReading; // Fifteen matches across five types, twelve slots. Without the overall cap a // search is an unbounded read wearing a bounded one's clothes. assert.equal(reading.results.length, 12); assert.equal(reading.truncated, true); assert.deepEqual(reading.counts, { account: 3, demand_deal: 3, supply_deal: 3, contract: 3, commitment: 3, }); }); test('every hit carries the type and id read-by-id needs, and a name to choose on', () => { const reading = assembleSearchResult('halcyon', { ...emptySets, contracts: [ { id: 'contract-1', title: 'DEMO — MSA — Halcyon Research', accountId: 'acct', contractType: 'msa', status: 'executed', side: 'demand', expiresAt: new Date('2026-10-05T00:00:00.000Z'), valueCents: null, }, ], accountNames: new Map([['acct', 'DEMO — Halcyon Research']]), }) as SearchReading & { results: Record[] }; assert.deepEqual(reading.results[0], { type: 'contract', id: 'contract-1', name: 'DEMO — MSA — Halcyon Research', accountName: 'DEMO — Halcyon Research', contractType: 'msa', status: 'executed', side: 'demand', expiresAt: '2026-10-05T00:00:00.000Z', // Null money is "not stated", never zero — the units rule in the system // prompt turns on exactly this distinction. valueCents: null, }); }); test('a search that matches nothing says so rather than returning a bare empty list', () => { const reading = assembleSearchResult('nobody', emptySets) as SearchReading; assert.equal(reading.results.length, 0); assert.equal(reading.truncated, false); assert.match(reading.headline, new RegExp(`None of the ${SEARCHABLE} account\\(s\\)`)); // Even an empty search states the size of what it looked through. assert.equal(reading.scope.matched, 0); assert.equal(reading.scope.total, SEARCHABLE); }); // --------------------------------------------------------------------------- // Renewals // --------------------------------------------------------------------------- const NOW = new Date('2026-08-13T12:00:00.000Z'); const DAY = 86_400_000; function contract(overrides: Partial & { id: string }): RenewalContract { return { title: `Contract ${overrides.id}`, side: 'demand', type: 'msa', isAutoRenew: false, noticeDays: null, expiresAt: new Date(NOW.getTime() + 365 * DAY), valueCents: null, ...overrides, }; } /** Contracts of every status on the book — the renewal list's denominator. */ const CONTRACTS_ON_BOOK = 20; interface RenewalReading { headline: string; truncated: boolean; scope: ResultScope; count: number; totalContracts: number; noticeWindowOpenCount: number; renewals: { id: string; renewalState: string; deadlineKind: string; daysUntilDeadline: number; deadlineAt: string; }[]; } test('a lapsed notice outranks a nearer expiry, because the decision is the deadline', () => { const reading = assembleRenewals( [ // Expires in 20 days with no notice term: the expiry is the deadline. { contract: contract({ id: 'soon', expiresAt: new Date(NOW.getTime() + 20 * DAY) }), accountName: 'Northwind' }, // Expires in 53 days, but the 60-day notice window opened a week ago. { contract: contract({ id: 'missed', expiresAt: new Date(NOW.getTime() + 53 * DAY), isAutoRenew: true, noticeDays: 60, valueCents: 876_635_509, }), accountName: 'Halcyon', }, ], { now: NOW, truncated: false, totalContracts: CONTRACTS_ON_BOOK }, ) as RenewalReading; assert.deepEqual(reading.renewals.map((row) => row.id), ['missed', 'soon']); const missed = reading.renewals[0]; assert.ok(missed); assert.equal(missed.renewalState, 'due'); assert.equal(missed.deadlineKind, 'renewal_notice'); // Negative days are the honest reading of a window that opened a week ago. assert.equal(missed.daysUntilDeadline, -7); assert.equal(reading.noticeWindowOpenCount, 1); assert.match(reading.headline, /which has already passed/); // Money is stated in dollars only in the headline; the row keeps raw cents. assert.match(reading.headline, /\$8,766,355\.09/); }); test('an open notice window on unpriced paper is not reported as worth nothing', () => { const reading = assembleRenewals( [ { // A master agreement carries the notice term; the money sits on the // order forms beneath it. Summing nulls to zero says "$0.00". contract: contract({ id: 'msa', expiresAt: new Date(NOW.getTime() + 53 * DAY), isAutoRenew: true, noticeDays: 60, valueCents: null, }), accountName: 'Halcyon', }, ], { now: NOW, truncated: false, totalContracts: CONTRACTS_ON_BOOK }, ) as RenewalReading; assert.equal(reading.noticeWindowOpenCount, 1); assert.doesNotMatch(reading.headline, /\$0\.00/); assert.match(reading.headline, /none of those contracts states a value of its own/); }); test('a contract that cannot auto-renew has an expiry deadline and no notice state', () => { const reading = assembleRenewals( [{ contract: contract({ id: 'plain' }), accountName: 'Verity Health AI' }], { now: NOW, truncated: false, totalContracts: CONTRACTS_ON_BOOK }, ) as RenewalReading; const [row] = reading.renewals; assert.ok(row); assert.equal(row.deadlineKind, 'expiry'); assert.equal(row.renewalState, 'not_applicable'); assert.equal(reading.noticeWindowOpenCount, 0); assert.doesNotMatch(reading.headline, /already passed/); }); test('the renewal count covers the whole set while the list is capped', () => { const rows = Array.from({ length: 14 }, (_, i) => ({ contract: contract({ id: `c${i}`, expiresAt: new Date(NOW.getTime() + (i + 1) * DAY) }), accountName: null, })); const reading = assembleRenewals(rows, { now: NOW, truncated: true, totalContracts: CONTRACTS_ON_BOOK }) as RenewalReading; assert.equal(reading.count, 14); assert.equal(reading.renewals.length, 8); assert.equal(reading.truncated, true); // A capped list quoted as a total is the defect this whole pattern exists to // prevent, so the hedge has to reach the headline. assert.match( reading.headline, new RegExp(`At least 14 of ${CONTRACTS_ON_BOOK} contract\\(s\\) on the book are executed`), ); assert.equal(reading.scope.matched, 14); assert.equal(reading.scope.total, CONTRACTS_ON_BOOK); }); test('an empty book states the absence rather than implying nothing is due', () => { const reading = assembleRenewals([], { now: NOW, side: 'supply', truncated: false, totalContracts: 8 }) as RenewalReading; assert.equal(reading.count, 0); assert.match(reading.headline, /None of the 8 supply-side contract\(s\) on the book/); }); // --------------------------------------------------------------------------- // Provider inventory // --------------------------------------------------------------------------- function offer(overrides: Partial & { gpuType: string }): InventoryOffer { return { accountId: 'provider-1', providerSlug: 'runpod', gpuCount: 8, interconnectType: 'Infiniband', region: 'us-east', country: 'US', securityTier: 'secure_cloud', stockStatus: 'Available', isSpot: false, onDemandPriceCents: 200, priceIsVariable: false, observedAt: NOW, ...overrides, }; } const providerNames = new Map([['provider-1', 'RunPod']]); /** Purchasable listings on the market with no filter at all: the denominator. */ const LISTINGS_ON_MARKET = 30; interface InventoryReading { headline: string; truncated: boolean; scope: ResultScope; count: number; totalListings: number; listings: { gpuType: string; providerName: string | null; onDemandPricePerGpuHourCents: number | null; }[]; } test('offers are cheapest first, and an unpriced one sorts last rather than free', () => { const reading = assembleInventoryResult( {}, [ offer({ gpuType: 'B200', onDemandPriceCents: 489 }), offer({ gpuType: 'QUOTE_ONLY', onDemandPriceCents: null }), offer({ gpuType: 'H100_80GB', onDemandPriceCents: 189 }), ], { truncated: false, providerNames, totalListings: LISTINGS_ON_MARKET, totalTruncated: false }, ) as InventoryReading; assert.deepEqual(reading.listings.map((row) => row.gpuType), [ 'H100_80GB', 'B200', 'QUOTE_ONLY', ]); assert.equal(reading.listings[0]?.providerName, 'RunPod'); // 189 cents is $1.89 per GPU-hour. Formatting it once in the headline is the // whole defence against a 30B model reporting "$189 per GPU-hour". assert.match(reading.headline, /cheapest on-demand is \$1\.89 per GPU-hour for H100_80GB/); assert.equal(reading.listings[0]?.onDemandPricePerGpuHourCents, 189); }); test('a GPU-type fragment matches the SKU, because a model asks for H100', () => { const reading = assembleInventoryResult( { gpuType: 'h100' }, [offer({ gpuType: 'H100_80GB' }), offer({ gpuType: 'H200' })], { truncated: false, providerNames, totalListings: LISTINGS_ON_MARKET, totalTruncated: false }, ) as InventoryReading; assert.equal(reading.count, 1); assert.equal(reading.listings[0]?.gpuType, 'H100_80GB'); }); test('the offer list is capped and the count is not', () => { const many = Array.from({ length: 20 }, (_, i) => offer({ gpuType: 'H200', onDemandPriceCents: 300 - i }), ); const reading = assembleInventoryResult({}, many, { truncated: true, providerNames, totalListings: 20, totalTruncated: true, }) as InventoryReading; assert.equal(reading.count, 20); assert.equal(reading.listings.length, 8); assert.equal(reading.listings[0]?.onDemandPricePerGpuHourCents, 281); assert.match(reading.headline, /20 of at least 20 purchasable listing\(s\) on the market/); assert.equal(reading.scope.truncated, true); }); test('no matching offer is reported as an absence, not as an empty market', () => { const reading = assembleInventoryResult({ gpuType: 'MI300X' }, [offer({ gpuType: 'H200' })], { truncated: false, providerNames, totalListings: LISTINGS_ON_MARKET, totalTruncated: false, }) as InventoryReading; assert.equal(reading.count, 0); assert.match( reading.headline, new RegExp(`None of the ${LISTINGS_ON_MARKET} purchasable listing\\(s\\) on the market matches`), ); });