Self-reference guard and entity casing fixes across both extraction paths
Two small commits fix a real production bug and a display annoyance in the counterparty and intake extraction paths. If you're pulling either extraction feature, pull both of these with it.
a9426b0c addresses a specific class of extraction failure: the LLM was sometimes returning the user's own organization as the counterparty. On a contract uploaded by a Kodex employee, the model returned "Kodex, Inc." - biased by the filename. The fix has two parts.
First, buildSystemPrompt() now injects the user's organization name from user_profiles.organisation directly into the system prompt: "the user's own organization is X - never return X as the counterparty." Second, an isSelfReference() guard normalizes company suffixes (Inc, LLC, Ltd, Corp, and about a dozen others) and nulls the extracted value if the model still returns a self-match despite the instruction. Both fixes apply symmetrically to counterpartyExtraction.ts and intakeAnalysis.ts.
The guard is forgiving by design: if organisation is unset on the user's profile, it's a no-op rather than an error. The only schema dependency is the organisation column on user_profiles.
282e57c1 adds normaliseEntityCase() to both extraction modules - about 117 lines of token-by-token case normalization. The problem: many contract preambles spell party names in ALL CAPS, so raw extraction returns "ADOBE INC." The function converts fully-uppercase or fully-lowercase strings to title case while preserving conventional suffix forms: "Inc." not "INC", "GmbH" not "GMBH", "plc" not "PLC". Short acronyms four characters or under (IBM, AT&T) are left alone.
Spotted something wrong? Or know the PR text has fresher detail than the writeup above?