@indigoai-us/hq-cli 5.230.2 → 5.231.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,18 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [5.231.0] — 2026-09-27
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
|
|
9
|
+
- Behind the off-by-default `checkpoint.ontology.first-name-people` flag, the
|
|
10
|
+
checkpoint ontology instructions tell the model to name a person by their
|
|
11
|
+
first name when neither the input nor the company's entities give more,
|
|
12
|
+
instead of leaving them out. With the flag on, apply also defers a one-word
|
|
13
|
+
person whose word starts an existing person's fuller name or alias (`John`
|
|
14
|
+
when `John Smith` exists), since the model cannot see the entity tree. With
|
|
15
|
+
the flag off the instructions and apply are unchanged.
|
|
16
|
+
|
|
5
17
|
## [5.230.2] — 2026-09-27
|
|
6
18
|
|
|
7
19
|
### Fixed
|
|
@@ -128,6 +128,13 @@ export declare function resolveCandidate(index: EntityIndex, type: string, canon
|
|
|
128
128
|
* (`Chaudhry Hassaan Saleem` and `Hassaan Saleem`).
|
|
129
129
|
*/
|
|
130
130
|
export declare function overlappingEntities(index: EntityIndex, type: string, canonical: string, aliases: string[]): string[];
|
|
131
|
+
/**
|
|
132
|
+
* Existing people a one-word person candidate may be: the word is the first
|
|
133
|
+
* word of their name or of one of their aliases, and that name has two words
|
|
134
|
+
* or more (`John` and `John Smith`). The model never sees the entity tree, so
|
|
135
|
+
* it cannot tell a first name that the company already holds in full.
|
|
136
|
+
*/
|
|
137
|
+
export declare function firstNameOverlap(index: EntityIndex, canonical: string): string[];
|
|
131
138
|
export declare function applyOntologyRun(options: ApplyOptions): ApplyReport;
|
|
132
139
|
export {};
|
|
133
140
|
//# sourceMappingURL=apply.d.ts.map
|
|
@@ -113,6 +113,30 @@ export function overlappingEntities(index, type, canonical, aliases) {
|
|
|
113
113
|
}
|
|
114
114
|
return [...paths].sort();
|
|
115
115
|
}
|
|
116
|
+
/**
|
|
117
|
+
* Existing people a one-word person candidate may be: the word is the first
|
|
118
|
+
* word of their name or of one of their aliases, and that name has two words
|
|
119
|
+
* or more (`John` and `John Smith`). The model never sees the entity tree, so
|
|
120
|
+
* it cannot tell a first name that the company already holds in full.
|
|
121
|
+
*/
|
|
122
|
+
export function firstNameOverlap(index, canonical) {
|
|
123
|
+
const words = normalizeEntityName(canonical, "person").split(" ");
|
|
124
|
+
if (words.length !== 1 || !words[0])
|
|
125
|
+
return [];
|
|
126
|
+
const prefix = entityKey("person", "");
|
|
127
|
+
const paths = new Set();
|
|
128
|
+
for (const map of [index.canonical, index.alias]) {
|
|
129
|
+
for (const [name, rels] of map) {
|
|
130
|
+
if (!name.startsWith(prefix))
|
|
131
|
+
continue;
|
|
132
|
+
const other = name.slice(prefix.length).split(" ");
|
|
133
|
+
if (other.length >= 2 && other[0] === words[0])
|
|
134
|
+
for (const rel of rels)
|
|
135
|
+
paths.add(rel);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
return [...paths].sort();
|
|
139
|
+
}
|
|
116
140
|
function readJson(file) {
|
|
117
141
|
return JSON.parse(fs.readFileSync(file, "utf8"));
|
|
118
142
|
}
|
|
@@ -335,6 +359,12 @@ export function applyOntologyRun(options) {
|
|
|
335
359
|
report.suspect_duplicates.push({ name: canonical, type: candidate.type, paths: overlap });
|
|
336
360
|
continue;
|
|
337
361
|
}
|
|
362
|
+
const firstName = plan.first_name_people === true && candidate.type === "person" ? firstNameOverlap(index, canonical) : [];
|
|
363
|
+
if (firstName.length > 0) {
|
|
364
|
+
note(report.deferred, "suspect_duplicate");
|
|
365
|
+
report.suspect_duplicates.push({ name: canonical, type: candidate.type, paths: firstName });
|
|
366
|
+
continue;
|
|
367
|
+
}
|
|
338
368
|
// Tier 5: create.
|
|
339
369
|
if (candidate.confidence < MIN_CREATE_CONFIDENCE) {
|
|
340
370
|
note(report.rejected, "low_confidence");
|
|
@@ -48,6 +48,17 @@ export declare const ENTITY_HINTS_FLAG = "checkpoint.ontology.entity-hints";
|
|
|
48
48
|
* hinted runs).
|
|
49
49
|
*/
|
|
50
50
|
export declare const NO_LINK_ALIASES_FLAG = "checkpoint.ontology.no-link-aliases";
|
|
51
|
+
/**
|
|
52
|
+
* A person the input and the company's entities give only a first name for is
|
|
53
|
+
* named by that first name instead of being left out. CO-44: on the CO-41
|
|
54
|
+
* grok-4.6 runs the model read "not a first name alone" as "skip them", and
|
|
55
|
+
* dropped people such as Amir and Sebastian, whose own entities carry only a
|
|
56
|
+
* first name. People were 24 of the 138 missed gold entities over three runs.
|
|
57
|
+
* The plan carries `first_name_people: true`, and apply then defers a one-word
|
|
58
|
+
* person whose word starts an existing person's fuller name or alias, since
|
|
59
|
+
* the model cannot see that `John Smith` already exists.
|
|
60
|
+
*/
|
|
61
|
+
export declare const FIRST_NAME_PEOPLE_FLAG = "checkpoint.ontology.first-name-people";
|
|
51
62
|
export declare const PLAN_FILE = "ontology-plan.json";
|
|
52
63
|
export declare const CANDIDATES_FILE = "ontology-candidates.json";
|
|
53
64
|
export declare const REPORT_FILE = "ontology-report.json";
|
|
@@ -116,6 +127,8 @@ export interface OntologyPlan {
|
|
|
116
127
|
multi_writer?: MultiWriterStart;
|
|
117
128
|
/** Present, as false, only when `checkpoint.ontology.no-link-aliases` was on for this plan. */
|
|
118
129
|
link_aliases?: false;
|
|
130
|
+
/** Set by checkpoint.ontology.first-name-people: apply defers a one-word person who may be an existing fuller name. */
|
|
131
|
+
first_name_people?: true;
|
|
119
132
|
inputs: PlanInput[];
|
|
120
133
|
/** The session's summary, decisions and learnings, for the `session` input. */
|
|
121
134
|
session_text: string | null;
|
|
@@ -160,6 +173,8 @@ export type PlanOutcome = {
|
|
|
160
173
|
};
|
|
161
174
|
export declare const READ_PATH_INSTRUCTION = "When an input has read_path, read that file (relative to the run directory) instead of path, with the same line range. It is the same text with an older annotator's entity lists and entity links removed.";
|
|
162
175
|
export declare const ENTITY_HINTS_INSTRUCTIONS: string[];
|
|
176
|
+
export declare const PERSON_NAME_INSTRUCTION = "Name a person by the full name the input or the company's entities give, not a first name alone.";
|
|
177
|
+
export declare const FIRST_NAME_PEOPLE_INSTRUCTION = "Name a person by the full name the input or the company's entities give. When neither gives more than a first name, name the person by that first name; do not leave them out.";
|
|
163
178
|
export declare function ledgerPath(hqRoot: string, company: OntologyCompany): string;
|
|
164
179
|
export declare function readLedger(hqRoot: string, company: OntologyCompany): Ledger | null;
|
|
165
180
|
export declare function writeLedger(hqRoot: string, company: OntologyCompany, ledger: Ledger): void;
|
|
@@ -52,6 +52,17 @@ export const ENTITY_HINTS_FLAG = "checkpoint.ontology.entity-hints";
|
|
|
52
52
|
* hinted runs).
|
|
53
53
|
*/
|
|
54
54
|
export const NO_LINK_ALIASES_FLAG = "checkpoint.ontology.no-link-aliases";
|
|
55
|
+
/**
|
|
56
|
+
* A person the input and the company's entities give only a first name for is
|
|
57
|
+
* named by that first name instead of being left out. CO-44: on the CO-41
|
|
58
|
+
* grok-4.6 runs the model read "not a first name alone" as "skip them", and
|
|
59
|
+
* dropped people such as Amir and Sebastian, whose own entities carry only a
|
|
60
|
+
* first name. People were 24 of the 138 missed gold entities over three runs.
|
|
61
|
+
* The plan carries `first_name_people: true`, and apply then defers a one-word
|
|
62
|
+
* person whose word starts an existing person's fuller name or alias, since
|
|
63
|
+
* the model cannot see that `John Smith` already exists.
|
|
64
|
+
*/
|
|
65
|
+
export const FIRST_NAME_PEOPLE_FLAG = "checkpoint.ontology.first-name-people";
|
|
55
66
|
export const PLAN_FILE = "ontology-plan.json";
|
|
56
67
|
export const CANDIDATES_FILE = "ontology-candidates.json";
|
|
57
68
|
export const REPORT_FILE = "ontology-report.json";
|
|
@@ -68,11 +79,13 @@ export const ENTITY_HINTS_INSTRUCTIONS = [
|
|
|
68
79
|
"A knowledge input's known_entities lists entities that already exist in the company and whose names appear in its text. When the input refers to one of them, under that name or another, use that entity's name and type exactly and do not name a new entity for it.",
|
|
69
80
|
"Skip rows of a glossary or translation table, file and directory paths, and names built from tags or slugs.",
|
|
70
81
|
];
|
|
82
|
+
export const PERSON_NAME_INSTRUCTION = "Name a person by the full name the input or the company's entities give, not a first name alone.";
|
|
83
|
+
export const FIRST_NAME_PEOPLE_INSTRUCTION = "Name a person by the full name the input or the company's entities give. When neither gives more than a first name, name the person by that first name; do not leave them out.";
|
|
71
84
|
const CANDIDATE_INSTRUCTIONS = [
|
|
72
85
|
`Write ${CANDIDATES_FILE} in the run directory as {"schema":"${CANDIDATES_SCHEMA}","candidates":[...]} and nothing else.`,
|
|
73
86
|
"Each candidate: {input, type, name, aliases, confidence, evidence}. input is one of this plan's input ids; type is person, project, company or concept; name is the entity's full proper name; aliases are other names the input uses for it (at most 5); confidence is 0 to 1; evidence is a short quote from the input.",
|
|
74
87
|
"Read only the files and line ranges this plan lists. For a signal, read its body and name the entities in missing_refs if the signal supports them.",
|
|
75
|
-
"Name the specific people, projects, products, companies and named concepts that the input says something about. That includes the company that owns this knowledge and its own products when the input describes them. Name a third-party tool, vendor or service only when a section of the input is about it; skip ones that appear in a list, a stack summary or a passing mention. Skip generic words, file names and headings.
|
|
88
|
+
"Name the specific people, projects, products, companies and named concepts that the input says something about. That includes the company that owns this knowledge and its own products when the input describes them. Name a third-party tool, vendor or service only when a section of the input is about it; skip ones that appear in a list, a stack summary or a passing mention. Skip generic words, file names and headings.",
|
|
76
89
|
"For the session input (its text is session_text in this plan), name only entities that already exist in the company and that the session did work on. Session candidates are recorded as links, never created.",
|
|
77
90
|
"Do not create, edit, move or delete anything under ontology/, signals/ or sources/ yourself.",
|
|
78
91
|
];
|
|
@@ -229,6 +242,7 @@ export async function planOntologyRun(options) {
|
|
|
229
242
|
const multiWriterOn = await options.readFlag(MULTI_WRITER_FLAG, company);
|
|
230
243
|
const hintsOn = await options.readFlag(ENTITY_HINTS_FLAG, company);
|
|
231
244
|
const noLinkAliases = await options.readFlag(NO_LINK_ALIASES_FLAG, company);
|
|
245
|
+
const firstNamePeople = await options.readFlag(FIRST_NAME_PEOPLE_FLAG, company);
|
|
232
246
|
const touched = sessionTouched(hqRoot, company, payload.files);
|
|
233
247
|
// A first run takes its boundary from the entity tree, so the ledger is
|
|
234
248
|
// refreshed before merge-back moves any `last_updated` forward.
|
|
@@ -342,6 +356,7 @@ export async function planOntologyRun(options) {
|
|
|
342
356
|
: {}),
|
|
343
357
|
...(multiWriter ? { multi_writer: multiWriter } : {}),
|
|
344
358
|
...(noLinkAliases ? { link_aliases: false } : {}),
|
|
359
|
+
...(firstNamePeople ? { first_name_people: true } : {}),
|
|
345
360
|
inputs,
|
|
346
361
|
session_text: sessionText,
|
|
347
362
|
pending_after_run: remaining,
|
|
@@ -355,7 +370,7 @@ export async function planOntologyRun(options) {
|
|
|
355
370
|
instructions: [
|
|
356
371
|
...CANDIDATE_INSTRUCTIONS.slice(0, 3),
|
|
357
372
|
...(inputs.some((input) => input.read_path) ? [READ_PATH_INSTRUCTION] : []),
|
|
358
|
-
CANDIDATE_INSTRUCTIONS[3]
|
|
373
|
+
`${CANDIDATE_INSTRUCTIONS[3]} ${firstNamePeople ? FIRST_NAME_PEOPLE_INSTRUCTION : PERSON_NAME_INSTRUCTION}`,
|
|
359
374
|
...(inputs.some((input) => input.known_entities) ? ENTITY_HINTS_INSTRUCTIONS : []),
|
|
360
375
|
...CANDIDATE_INSTRUCTIONS.slice(4),
|
|
361
376
|
],
|